From 84d8ae5df727252866e4c30b8a51c2210c28dcb1 Mon Sep 17 00:00:00 2001 From: Magnus Jedvert Date: Wed, 20 Dec 2017 15:12:10 +0100 Subject: [PATCH] Android: Use scoped java refs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Sami Kalliomäki Cr-Commit-Position: refs/heads/master@{#21387} --- modules/utility/include/helpers_android.h | 17 - .../test/videoprocessor_integrationtest.cc | 28 +- sdk/android/BUILD.gn | 30 ++ sdk/android/api/org/webrtc/AudioTrack.java | 3 +- .../CallSessionFileRotatingLogSink.java | 3 +- sdk/android/api/org/webrtc/DataChannel.java | 41 +- .../webrtc/DefaultAudioProcessingFactory.java | 3 +- sdk/android/api/org/webrtc/DtmfSender.java | 11 +- .../webrtc/HardwareVideoEncoderFactory.java | 8 +- .../org/webrtc/MediaCodecVideoEncoder.java | 7 +- sdk/android/api/org/webrtc/MediaSource.java | 5 +- sdk/android/api/org/webrtc/MediaStream.java | 31 +- .../api/org/webrtc/MediaStreamTrack.java | 25 +- sdk/android/api/org/webrtc/Metrics.java | 10 +- .../api/org/webrtc/PeerConnection.java | 143 ++++--- .../api/org/webrtc/PeerConnectionFactory.java | 136 +++---- sdk/android/api/org/webrtc/RtpReceiver.java | 33 +- sdk/android/api/org/webrtc/RtpSender.java | 25 +- .../webrtc/SoftwareVideoDecoderFactory.java | 2 +- .../webrtc/SoftwareVideoEncoderFactory.java | 4 +- .../api/org/webrtc/TurnCustomizer.java | 5 +- .../api/org/webrtc/VideoDecoderFallback.java | 5 +- .../api/org/webrtc/VideoEncoderFallback.java | 5 +- .../api/org/webrtc/VideoFileRenderer.java | 5 +- sdk/android/api/org/webrtc/VideoFrame.java | 5 +- .../api/org/webrtc/VideoFrameDrawer.java | 2 +- sdk/android/api/org/webrtc/VideoRenderer.java | 15 +- sdk/android/api/org/webrtc/VideoSource.java | 4 +- sdk/android/api/org/webrtc/VideoTrack.java | 8 +- sdk/android/api/org/webrtc/YuvConverter.java | 4 +- sdk/android/api/org/webrtc/YuvHelper.java | 25 +- .../AndroidVideoTrackSourceObserver.java | 15 +- .../src/java/org/webrtc/Histogram.java | 1 + .../src/java/org/webrtc/JNINamespace.java | 26 ++ .../src/java/org/webrtc/JniCommon.java | 9 +- .../src/java/org/webrtc/NV12Buffer.java | 1 + .../src/java/org/webrtc/NV21Buffer.java | 1 + .../src/java/org/webrtc/VP8Decoder.java | 8 +- .../src/java/org/webrtc/VP8Encoder.java | 8 +- .../src/java/org/webrtc/VP9Decoder.java | 10 +- .../src/java/org/webrtc/VP9Encoder.java | 10 +- sdk/android/src/jni/androidhistogram.cc | 36 +- sdk/android/src/jni/androidmediadecoder.cc | 68 ++-- sdk/android/src/jni/androidmediaencoder.cc | 94 +++-- sdk/android/src/jni/androidmetrics.cc | 17 +- .../src/jni/androidvideotracksource.cc | 90 ++--- sdk/android/src/jni/androidvideotracksource.h | 4 +- sdk/android/src/jni/class_loader.cc | 27 +- sdk/android/src/jni/class_loader.h | 4 +- sdk/android/src/jni/encodedimage.cc | 20 +- sdk/android/src/jni/encodedimage.h | 11 +- .../src/jni/hardwarevideoencoderfactory.cc | 14 +- sdk/android/src/jni/jni_common.cc | 40 +- sdk/android/src/jni/jni_generator_helper.cc | 11 +- sdk/android/src/jni/jni_generator_helper.h | 29 +- sdk/android/src/jni/jni_helpers.cc | 138 ++++--- sdk/android/src/jni/jni_helpers.h | 170 ++++---- sdk/android/src/jni/nv12buffer.cc | 51 +-- sdk/android/src/jni/nv21buffer.cc | 49 +-- .../src/jni/pc/androidnetworkmonitor.cc | 52 +-- .../src/jni/pc/androidnetworkmonitor.h | 15 +- sdk/android/src/jni/pc/audiotrack.cc | 12 +- .../jni/pc/callsessionfilerotatinglogsink.cc | 44 +-- sdk/android/src/jni/pc/datachannel.cc | 99 +++-- sdk/android/src/jni/pc/datachannel.h | 8 +- .../jni/pc/defaultaudioprocessingfactory.cc | 7 +- sdk/android/src/jni/pc/dtmfsender.cc | 48 +-- sdk/android/src/jni/pc/icecandidate.cc | 48 ++- sdk/android/src/jni/pc/icecandidate.h | 36 +- sdk/android/src/jni/pc/logging.cc | 4 +- sdk/android/src/jni/pc/mediaconstraints.cc | 15 +- sdk/android/src/jni/pc/mediaconstraints.h | 3 +- sdk/android/src/jni/pc/mediasource.cc | 8 +- sdk/android/src/jni/pc/mediastream.cc | 63 ++- sdk/android/src/jni/pc/mediastream.h | 6 +- sdk/android/src/jni/pc/mediastreamtrack.cc | 52 ++- sdk/android/src/jni/pc/mediastreamtrack.h | 8 +- sdk/android/src/jni/pc/null_video.cc | 25 +- sdk/android/src/jni/pc/peerconnection.cc | 371 ++++++++---------- sdk/android/src/jni/pc/peerconnection.h | 11 +- .../src/jni/pc/peerconnectionfactory.cc | 260 ++++++------ .../pc/rtcstatscollectorcallbackwrapper.cc | 24 +- .../jni/pc/rtcstatscollectorcallbackwrapper.h | 5 +- sdk/android/src/jni/pc/rtpparameters.cc | 31 +- sdk/android/src/jni/pc/rtpparameters.h | 8 +- sdk/android/src/jni/pc/rtpreceiver.cc | 76 ++-- sdk/android/src/jni/pc/rtpreceiver.h | 8 +- sdk/android/src/jni/pc/rtpsender.cc | 59 ++- sdk/android/src/jni/pc/rtpsender.h | 6 +- sdk/android/src/jni/pc/sdpobserver.cc | 13 +- sdk/android/src/jni/pc/sdpobserver.h | 8 +- sdk/android/src/jni/pc/sessiondescription.cc | 15 +- sdk/android/src/jni/pc/sessiondescription.h | 8 +- sdk/android/src/jni/pc/statsobserver.cc | 38 +- sdk/android/src/jni/pc/statsobserver.h | 4 +- sdk/android/src/jni/pc/turncustomizer.cc | 14 +- sdk/android/src/jni/pc/turncustomizer.h | 5 +- sdk/android/src/jni/pc/video.cc | 20 +- sdk/android/src/jni/pc/video.h | 17 +- sdk/android/src/jni/scoped_java_ref.h | 205 ++++++++++ sdk/android/src/jni/surfacetexturehelper.cc | 38 +- sdk/android/src/jni/surfacetexturehelper.h | 28 +- sdk/android/src/jni/video_renderer.cc | 98 +++-- sdk/android/src/jni/videocodecinfo.cc | 10 +- sdk/android/src/jni/videocodecinfo.h | 9 +- sdk/android/src/jni/videocodecstatus.cc | 5 +- sdk/android/src/jni/videocodecstatus.h | 6 +- .../src/jni/videodecoderfactorywrapper.cc | 14 +- .../src/jni/videodecoderfactorywrapper.h | 5 +- sdk/android/src/jni/videodecoderfallback.cc | 12 +- sdk/android/src/jni/videodecoderwrapper.cc | 48 +-- sdk/android/src/jni/videodecoderwrapper.h | 14 +- .../src/jni/videoencoderfactorywrapper.cc | 28 +- .../src/jni/videoencoderfactorywrapper.h | 5 +- sdk/android/src/jni/videoencoderfallback.cc | 12 +- sdk/android/src/jni/videoencoderwrapper.cc | 89 ++--- sdk/android/src/jni/videoencoderwrapper.h | 19 +- sdk/android/src/jni/videofilerenderer.cc | 54 +-- sdk/android/src/jni/videoframe.cc | 161 ++++---- sdk/android/src/jni/videoframe.h | 28 +- sdk/android/src/jni/videotrack.cc | 40 +- sdk/android/src/jni/vp8codec.cc | 14 +- sdk/android/src/jni/vp9codec.cc | 26 +- .../src/jni/wrapped_native_i420_buffer.cc | 31 +- .../src/jni/wrapped_native_i420_buffer.h | 3 +- sdk/android/src/jni/wrappednativecodec.cc | 12 +- sdk/android/src/jni/wrappednativecodec.h | 13 +- sdk/android/src/jni/yuvhelper.cc | 91 ++--- 128 files changed, 2324 insertions(+), 1958 deletions(-) create mode 100644 sdk/android/src/java/org/webrtc/JNINamespace.java create mode 100644 sdk/android/src/jni/scoped_java_ref.h diff --git a/modules/utility/include/helpers_android.h b/modules/utility/include/helpers_android.h index c1d9ad87ec..1d23653d5d 100644 --- a/modules/utility/include/helpers_android.h +++ b/modules/utility/include/helpers_android.h @@ -65,23 +65,6 @@ class AttachThreadScoped { JNIEnv* env_; }; -// Scoped holder for global Java refs. -template // T is jclass, jobject, jintArray, etc. -class ScopedGlobalRef { - public: - ScopedGlobalRef(JNIEnv* jni, T obj) - : jni_(jni), obj_(static_cast(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_ diff --git a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc index 98431b8965..dc9b146560 100644 --- a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc +++ b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc @@ -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 factory_class = + jni::GetClass(env, "org/webrtc/HardwareVideoEncoderFactory"); jmethodID factory_constructor = env->GetMethodID( - factory_class, "", "(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(), "", "(Lorg/webrtc/EglBase$Context;ZZ)V"); + jni::ScopedJavaLocalRef 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( 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 factory_class = + jni::GetClass(env, "org/webrtc/HardwareVideoDecoderFactory"); jmethodID factory_constructor = env->GetMethodID( - factory_class, "", "(Lorg/webrtc/EglBase$Context;)V"); - jobject factory_object = env->NewObject(factory_class, factory_constructor, - nullptr /* shared_context */); + factory_class.obj(), "", "(Lorg/webrtc/EglBase$Context;)V"); + jni::ScopedJavaLocalRef factory_object( + env, env->NewObject(factory_class.obj(), factory_constructor, + nullptr /* shared_context */)); decoder_factory = rtc::MakeUnique( env, factory_object); #elif defined(WEBRTC_IOS) diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index 4e04ac895b..1e98755845 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -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", diff --git a/sdk/android/api/org/webrtc/AudioTrack.java b/sdk/android/api/org/webrtc/AudioTrack.java index 6b71353610..6663666b40 100644 --- a/sdk/android/api/org/webrtc/AudioTrack.java +++ b/sdk/android/api/org/webrtc/AudioTrack.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); } diff --git a/sdk/android/api/org/webrtc/CallSessionFileRotatingLogSink.java b/sdk/android/api/org/webrtc/CallSessionFileRotatingLogSink.java index 132248797d..b55c042ed3 100644 --- a/sdk/android/api/org/webrtc/CallSessionFileRotatingLogSink.java +++ b/sdk/android/api/org/webrtc/CallSessionFileRotatingLogSink.java @@ -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); } diff --git a/sdk/android/api/org/webrtc/DataChannel.java b/sdk/android/api/org/webrtc/DataChannel.java index 883025e960..21873df2a0 100644 --- a/sdk/android/api/org/webrtc/DataChannel.java +++ b/sdk/android/api/org/webrtc/DataChannel.java @@ -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); }; diff --git a/sdk/android/api/org/webrtc/DefaultAudioProcessingFactory.java b/sdk/android/api/org/webrtc/DefaultAudioProcessingFactory.java index 6fcfe23327..fd4c45af6d 100644 --- a/sdk/android/api/org/webrtc/DefaultAudioProcessingFactory.java +++ b/sdk/android/api/org/webrtc/DefaultAudioProcessingFactory.java @@ -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); } diff --git a/sdk/android/api/org/webrtc/DtmfSender.java b/sdk/android/api/org/webrtc/DtmfSender.java index d284313dcb..4dcb794405 100644 --- a/sdk/android/api/org/webrtc/DtmfSender.java +++ b/sdk/android/api/org/webrtc/DtmfSender.java @@ -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); }; diff --git a/sdk/android/api/org/webrtc/HardwareVideoEncoderFactory.java b/sdk/android/api/org/webrtc/HardwareVideoEncoderFactory.java index ef25a8c908..6fc747ece4 100644 --- a/sdk/android/api/org/webrtc/HardwareVideoEncoderFactory.java +++ b/sdk/android/api/org/webrtc/HardwareVideoEncoderFactory.java @@ -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 params1, Map params2); } diff --git a/sdk/android/api/org/webrtc/MediaCodecVideoEncoder.java b/sdk/android/api/org/webrtc/MediaCodecVideoEncoder.java index 6b98598705..db82be96b7 100644 --- a/sdk/android/api/org/webrtc/MediaCodecVideoEncoder.java +++ b/sdk/android/api/org/webrtc/MediaCodecVideoEncoder.java @@ -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); } diff --git a/sdk/android/api/org/webrtc/MediaSource.java b/sdk/android/api/org/webrtc/MediaSource.java index c0421f7133..8e6da176cf 100644 --- a/sdk/android/api/org/webrtc/MediaSource.java +++ b/sdk/android/api/org/webrtc/MediaSource.java @@ -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); } diff --git a/sdk/android/api/org/webrtc/MediaStream.java b/sdk/android/api/org/webrtc/MediaStream.java index 73a781633d..d66d844936 100644 --- a/sdk/android/api/org/webrtc/MediaStream.java +++ b/sdk/android/api/org/webrtc/MediaStream.java @@ -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); } diff --git a/sdk/android/api/org/webrtc/MediaStreamTrack.java b/sdk/android/api/org/webrtc/MediaStreamTrack.java index 60149dbb70..449ca75dbd 100644 --- a/sdk/android/api/org/webrtc/MediaStreamTrack.java +++ b/sdk/android/api/org/webrtc/MediaStreamTrack.java @@ -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); } diff --git a/sdk/android/api/org/webrtc/Metrics.java b/sdk/android/api/org/webrtc/Metrics.java index 1e188516ec..43cf439c0b 100644 --- a/sdk/android/api/org/webrtc/Metrics.java +++ b/sdk/android/api/org/webrtc/Metrics.java @@ -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(); } diff --git a/sdk/android/api/org/webrtc/PeerConnection.java b/sdk/android/api/org/webrtc/PeerConnection.java index 8eddfa8455..d8993d5be1 100644 --- a/sdk/android/api/org/webrtc/PeerConnection.java +++ b/sdk/android/api/org/webrtc/PeerConnection.java @@ -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 getNativeSenders(); - - private native List 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 nativeGetSenders(); + private native List nativeGetReceivers(); + private native boolean nativeStartRtcEventLog(int file_descriptor, int max_size_bytes); + private native void nativeStopRtcEventLog(); } diff --git a/sdk/android/api/org/webrtc/PeerConnectionFactory.java b/sdk/android/api/org/webrtc/PeerConnectionFactory.java index c8c5b9a420..5c9dc616c0 100644 --- a/sdk/android/api/org/webrtc/PeerConnectionFactory.java +++ b/sdk/android/api/org/webrtc/PeerConnectionFactory.java @@ -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); } diff --git a/sdk/android/api/org/webrtc/RtpReceiver.java b/sdk/android/api/org/webrtc/RtpReceiver.java index ac296952ad..0c9de5649a 100644 --- a/sdk/android/api/org/webrtc/RtpReceiver.java +++ b/sdk/android/api/org/webrtc/RtpReceiver.java @@ -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); }; diff --git a/sdk/android/api/org/webrtc/RtpSender.java b/sdk/android/api/org/webrtc/RtpSender.java index 8100ff7785..9675d9d2e6 100644 --- a/sdk/android/api/org/webrtc/RtpSender.java +++ b/sdk/android/api/org/webrtc/RtpSender.java @@ -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); }; diff --git a/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java b/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java index 996c299c8d..cfe76a480a 100644 --- a/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java +++ b/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java @@ -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(); } diff --git a/sdk/android/api/org/webrtc/SoftwareVideoEncoderFactory.java b/sdk/android/api/org/webrtc/SoftwareVideoEncoderFactory.java index 7cc3f9c956..3481915b79 100644 --- a/sdk/android/api/org/webrtc/SoftwareVideoEncoderFactory.java +++ b/sdk/android/api/org/webrtc/SoftwareVideoEncoderFactory.java @@ -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 codecs = new ArrayList(); codecs.add(new VideoCodecInfo("VP8", new HashMap<>())); - if (VP9Encoder.isSupported()) { + if (VP9Encoder.nativeIsSupported()) { codecs.add(new VideoCodecInfo("VP9", new HashMap<>())); } diff --git a/sdk/android/api/org/webrtc/TurnCustomizer.java b/sdk/android/api/org/webrtc/TurnCustomizer.java index f2cdcb122f..1c2b080db6 100644 --- a/sdk/android/api/org/webrtc/TurnCustomizer.java +++ b/sdk/android/api/org/webrtc/TurnCustomizer.java @@ -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() { diff --git a/sdk/android/api/org/webrtc/VideoDecoderFallback.java b/sdk/android/api/org/webrtc/VideoDecoderFallback.java index 67e746f83c..f748da78b2 100644 --- a/sdk/android/api/org/webrtc/VideoDecoderFallback.java +++ b/sdk/android/api/org/webrtc/VideoDecoderFallback.java @@ -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); } diff --git a/sdk/android/api/org/webrtc/VideoEncoderFallback.java b/sdk/android/api/org/webrtc/VideoEncoderFallback.java index 7894da9026..59e7ffc271 100644 --- a/sdk/android/api/org/webrtc/VideoEncoderFallback.java +++ b/sdk/android/api/org/webrtc/VideoEncoderFallback.java @@ -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); } diff --git a/sdk/android/api/org/webrtc/VideoFileRenderer.java b/sdk/android/api/org/webrtc/VideoFileRenderer.java index 06b433c47d..20ca839495 100644 --- a/sdk/android/api/org/webrtc/VideoFileRenderer.java +++ b/sdk/android/api/org/webrtc/VideoFileRenderer.java @@ -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 " diff --git a/sdk/android/api/org/webrtc/VideoFrame.java b/sdk/android/api/org/webrtc/VideoFrame.java index 3ee368d2ea..3e8a1e4d8d 100644 --- a/sdk/android/api/org/webrtc/VideoFrame.java +++ b/sdk/android/api/org/webrtc/VideoFrame.java @@ -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); diff --git a/sdk/android/api/org/webrtc/VideoFrameDrawer.java b/sdk/android/api/org/webrtc/VideoFrameDrawer.java index 3d3125e87a..491fd054c2 100644 --- a/sdk/android/api/org/webrtc/VideoFrameDrawer.java +++ b/sdk/android/api/org/webrtc/VideoFrameDrawer.java @@ -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; } diff --git a/sdk/android/api/org/webrtc/VideoRenderer.java b/sdk/android/api/org/webrtc/VideoRenderer.java index 8301c10042..3dd3f1aae9 100644 --- a/sdk/android/api/org/webrtc/VideoRenderer.java +++ b/sdk/android/api/org/webrtc/VideoRenderer.java @@ -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); } diff --git a/sdk/android/api/org/webrtc/VideoSource.java b/sdk/android/api/org/webrtc/VideoSource.java index d9531cd9a5..425f86152d 100644 --- a/sdk/android/api/org/webrtc/VideoSource.java +++ b/sdk/android/api/org/webrtc/VideoSource.java @@ -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); } diff --git a/sdk/android/api/org/webrtc/VideoTrack.java b/sdk/android/api/org/webrtc/VideoTrack.java index 7839a03998..e0eebeda0d 100644 --- a/sdk/android/api/org/webrtc/VideoTrack.java +++ b/sdk/android/api/org/webrtc/VideoTrack.java @@ -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 renderers = new ArrayList<>(); private final IdentityHashMap sinks = new IdentityHashMap(); @@ -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); } diff --git a/sdk/android/api/org/webrtc/YuvConverter.java b/sdk/android/api/org/webrtc/YuvConverter.java index 844ab58bfe..31db0dd610 100644 --- a/sdk/android/api/org/webrtc/YuvConverter.java +++ b/sdk/android/api/org/webrtc/YuvConverter.java @@ -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). */ diff --git a/sdk/android/api/org/webrtc/YuvHelper.java b/sdk/android/api/org/webrtc/YuvHelper.java index 344d5d962a..2d6877bc33 100644 --- a/sdk/android/api/org/webrtc/YuvHelper.java +++ b/sdk/android/api/org/webrtc/YuvHelper.java @@ -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); } diff --git a/sdk/android/src/java/org/webrtc/AndroidVideoTrackSourceObserver.java b/sdk/android/src/java/org/webrtc/AndroidVideoTrackSourceObserver.java index 123204791f..ccbc824e15 100644 --- a/sdk/android/src/java/org/webrtc/AndroidVideoTrackSourceObserver.java +++ b/sdk/android/src/java/org/webrtc/AndroidVideoTrackSourceObserver.java @@ -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); } diff --git a/sdk/android/src/java/org/webrtc/Histogram.java b/sdk/android/src/java/org/webrtc/Histogram.java index 877986134a..9043e4b0c8 100644 --- a/sdk/android/src/java/org/webrtc/Histogram.java +++ b/sdk/android/src/java/org/webrtc/Histogram.java @@ -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; diff --git a/sdk/android/src/java/org/webrtc/JNINamespace.java b/sdk/android/src/java/org/webrtc/JNINamespace.java new file mode 100644 index 0000000000..f0fe20f157 --- /dev/null +++ b/sdk/android/src/java/org/webrtc/JNINamespace.java @@ -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(); +} diff --git a/sdk/android/src/java/org/webrtc/JniCommon.java b/sdk/android/src/java/org/webrtc/JniCommon.java index 9a8455bd56..600477e46a 100644 --- a/sdk/android/src/java/org/webrtc/JniCommon.java +++ b/sdk/android/src/java/org/webrtc/JniCommon.java @@ -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); } diff --git a/sdk/android/src/java/org/webrtc/NV12Buffer.java b/sdk/android/src/java/org/webrtc/NV12Buffer.java index 9c5df02562..cdef36b0a8 100644 --- a/sdk/android/src/java/org/webrtc/NV12Buffer.java +++ b/sdk/android/src/java/org/webrtc/NV12Buffer.java @@ -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; diff --git a/sdk/android/src/java/org/webrtc/NV21Buffer.java b/sdk/android/src/java/org/webrtc/NV21Buffer.java index 3a528be6df..b3ce41a337 100644 --- a/sdk/android/src/java/org/webrtc/NV21Buffer.java +++ b/sdk/android/src/java/org/webrtc/NV21Buffer.java @@ -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; diff --git a/sdk/android/src/java/org/webrtc/VP8Decoder.java b/sdk/android/src/java/org/webrtc/VP8Decoder.java index ea7ff9730d..f9d5165212 100644 --- a/sdk/android/src/java/org/webrtc/VP8Decoder.java +++ b/sdk/android/src/java/org/webrtc/VP8Decoder.java @@ -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(); } diff --git a/sdk/android/src/java/org/webrtc/VP8Encoder.java b/sdk/android/src/java/org/webrtc/VP8Encoder.java index 4157568670..f9967426f6 100644 --- a/sdk/android/src/java/org/webrtc/VP8Encoder.java +++ b/sdk/android/src/java/org/webrtc/VP8Encoder.java @@ -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() { diff --git a/sdk/android/src/java/org/webrtc/VP9Decoder.java b/sdk/android/src/java/org/webrtc/VP9Decoder.java index 619ba91768..52d8f02c00 100644 --- a/sdk/android/src/java/org/webrtc/VP9Decoder.java +++ b/sdk/android/src/java/org/webrtc/VP9Decoder.java @@ -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(); } diff --git a/sdk/android/src/java/org/webrtc/VP9Encoder.java b/sdk/android/src/java/org/webrtc/VP9Encoder.java index 7839ab9981..ca9398ebf9 100644 --- a/sdk/android/src/java/org/webrtc/VP9Encoder.java +++ b/sdk/android/src/java/org/webrtc/VP9Encoder.java @@ -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(); } diff --git a/sdk/android/src/jni/androidhistogram.cc b/sdk/android/src/jni/androidhistogram.cc index 0cb0e00f15..9ef15b3b75 100644 --- a/sdk/android/src/jni/androidhistogram.cc +++ b/sdk/android/src/jni/androidhistogram.cc @@ -11,6 +11,7 @@ #include #include +#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&, + const JavaParamRef& 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&, + const JavaParamRef& 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&, + jlong histogram, + jint sample) { if (histogram) { HistogramAdd(reinterpret_cast(histogram), sample); } diff --git a/sdk/android/src/jni/androidmediadecoder.cc b/sdk/android/src/jni/androidmediadecoder.cc index 390d357fe3..93f8f4672b 100644 --- a/sdk/android/src/jni/androidmediadecoder.cc +++ b/sdk/android/src/jni/androidmediadecoder.cc @@ -130,10 +130,10 @@ class MediaCodecVideoDecoder : public VideoDecoder, public rtc::MessageHandler { // returns. std::unique_ptr codec_thread_; // Thread on which to operate MediaCodec. - ScopedGlobalRef j_media_codec_video_decoder_; + ScopedJavaGlobalRef j_media_codec_video_decoder_; // Global references; must be deleted in Release(). - std::vector> input_buffers_; + std::vector> 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(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 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(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>( - jni, input_buffers, - [](JNIEnv* env, jobject o) { return ScopedGlobalRef(env, o); }); + ScopedJavaLocalRef input_buffers = + Java_MediaCodecVideoDecoder_getInputBuffers(jni, + j_media_codec_video_decoder_); + input_buffers_ = JavaToNativeVector>( + jni, input_buffers, [](JNIEnv* env, const JavaRef& o) { + return ScopedJavaGlobalRef(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(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(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 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 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 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 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(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; diff --git a/sdk/android/src/jni/androidmediaencoder.cc b/sdk/android/src/jni/androidmediaencoder.cc index e1d1413d9e..174fc55b19 100644 --- a/sdk/android/src/jni/androidmediaencoder.cc +++ b/sdk/android/src/jni/androidmediaencoder.cc @@ -176,7 +176,7 @@ class MediaCodecVideoEncoder : public VideoEncoder { // frame. bool EncodeJavaFrame(JNIEnv* jni, bool key_frame, - jobject frame, + const JavaRef& 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 j_media_codec_video_encoder_; + ScopedJavaGlobalRef 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> input_buffers_; + std::vector> 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 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(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 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>( - jni, input_buffers, [](JNIEnv* env, jobject o) { - return ScopedGlobalRef(env, o); + input_buffers_ = JavaToNativeVector>( + jni, input_buffers, [](JNIEnv* env, const JavaRef& o) { + return ScopedJavaGlobalRef(env, o); }); - for (const ScopedGlobalRef& buffer : input_buffers_) { - int64_t yuv_buffer_capacity = jni->GetDirectBufferCapacity(*buffer); + for (const ScopedJavaGlobalRef& 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(jni->GetDirectBufferAddress(j_input_buffer)); + uint8_t* yuv_buffer = reinterpret_cast( + 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(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& 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 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 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( - 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&, + jlong native_encoder, + jint input_buffer, + const JavaParamRef& j_buffer_y, + jint stride_y, + const JavaParamRef& j_buffer_u, + jint stride_u, + const JavaParamRef& j_buffer_v, + jint stride_v) { uint8_t* buffer_y = - static_cast(jni->GetDirectBufferAddress(j_buffer_y)); + static_cast(jni->GetDirectBufferAddress(j_buffer_y.obj())); uint8_t* buffer_u = - static_cast(jni->GetDirectBufferAddress(j_buffer_u)); + static_cast(jni->GetDirectBufferAddress(j_buffer_u.obj())); uint8_t* buffer_v = - static_cast(jni->GetDirectBufferAddress(j_buffer_v)); + static_cast(jni->GetDirectBufferAddress(j_buffer_v.obj())); RTC_DCHECK(buffer_y) << "GetDirectBufferAddress returned null. Ensure that " "getDataY returns a direct ByteBuffer."; diff --git a/sdk/android/src/jni/androidmetrics.cc b/sdk/android/src/jni/androidmetrics.cc index c2deeda5b4..68b1047538 100644 --- a/sdk/android/src/jni/androidmetrics.cc +++ b/sdk/android/src/jni/androidmetrics.cc @@ -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&) { 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 JNI_Metrics_GetAndReset( + JNIEnv* jni, + const JavaParamRef& jcaller) { + ScopedJavaLocalRef j_metrics = Java_Metrics_Constructor(jni); std::map> histograms; metrics::GetAndReset(&histograms); for (const auto& kv : histograms) { // Create and add samples to |HistogramInfo|. - jobject j_info = Java_HistogramInfo_Constructor( + ScopedJavaLocalRef j_info = Java_HistogramInfo_Constructor( jni, kv.second->min, kv.second->max, static_cast(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 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; diff --git a/sdk/android/src/jni/androidvideotracksource.cc b/sdk/android/src/jni/androidvideotracksource.cc index bacc2b8865..7df2cb5dc1 100644 --- a/sdk/android/src/jni/androidvideotracksource.cc +++ b/sdk/android/src/jni/androidvideotracksource.cc @@ -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& 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& 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&, jlong j_source, - jbyteArray j_frame, + const JavaParamRef& 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&, jlong j_source, jint j_width, jint j_height, jint j_oes_texture_id, - jfloatArray j_transform_matrix, + const JavaParamRef& 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&, + jlong j_source, + jint j_width, + jint j_height, + jint j_rotation, + jlong j_timestamp_ns, + const JavaParamRef& 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&, + 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&, + 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&, + jlong j_source, + jint j_width, + jint j_height, + jint j_fps) { RTC_LOG(LS_INFO) << "VideoSource_nativeAdaptOutputFormat"; AndroidVideoTrackSource* source = AndroidVideoTrackSourceFromJavaProxy(j_source); diff --git a/sdk/android/src/jni/androidvideotracksource.h b/sdk/android/src/jni/androidvideotracksource.h index 2050632fd6..c40203de53 100644 --- a/sdk/android/src/jni/androidvideotracksource.h +++ b/sdk/android/src/jni/androidvideotracksource.h @@ -30,7 +30,7 @@ class AndroidVideoTrackSource : public rtc::AdaptedVideoTrackSource { public: AndroidVideoTrackSource(rtc::Thread* signaling_thread, JNIEnv* jni, - jobject j_surface_texture_helper, + const JavaRef& 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& j_video_frame_buffer); void OnOutputFormatRequest(int width, int height, int fps); diff --git a/sdk/android/src/jni/class_loader.cc b/sdk/android/src/jni/class_loader.cc index 84b3e9062a..d02318aa82 100644 --- a/sdk/android/src/jni/class_loader.cc +++ b/sdk/android/src/jni/class_loader.cc @@ -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( 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 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( - env->CallObjectMethod(class_loader_, load_class_method_, jstr)); + ScopedJavaLocalRef j_name = NativeToJavaString(env, name); + const jclass clazz = static_cast(env->CallObjectMethod( + class_loader_.obj(), load_class_method_, j_name.obj())); CHECK_EXCEPTION(env); - return clazz; + return ScopedJavaLocalRef(env, clazz); } private: + ScopedJavaGlobalRef 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 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(env, env->FindClass(name)) + : g_class_loader->FindClass(env, name); } } // namespace jni diff --git a/sdk/android/src/jni/class_loader.h b/sdk/android/src/jni/class_loader.h index 52bb1ba523..90c46d71fe 100644 --- a/sdk/android/src/jni/class_loader.h +++ b/sdk/android/src/jni/class_loader.h @@ -19,6 +19,8 @@ #include +#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 GetClass(JNIEnv* env, const char* name); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/encodedimage.cc b/sdk/android/src/jni/encodedimage.cc index 81c5caa761..d24c25a3a0 100644 --- a/sdk/android/src/jni/encodedimage.cc +++ b/sdk/android/src/jni/encodedimage.cc @@ -18,22 +18,28 @@ namespace webrtc { namespace jni { -jobject NativeToJavaFrameType(JNIEnv* env, FrameType frame_type) { +ScopedJavaLocalRef 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 NativeToJavaEncodedImage( + JNIEnv* jni, + const EncodedImage& image) { + ScopedJavaLocalRef buffer = + NewDirectByteBuffer(jni, image._buffer, image._length); + ScopedJavaLocalRef frame_type = + NativeToJavaFrameType(jni, image._frameType); + ScopedJavaLocalRef 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(image.rotation_), image._completeFrame, qp); } -jobjectArray NativeToJavaFrameTypeArray( +ScopedJavaLocalRef NativeToJavaFrameTypeArray( JNIEnv* env, const std::vector& frame_types) { return NativeToJavaObjectArray( diff --git a/sdk/android/src/jni/encodedimage.h b/sdk/android/src/jni/encodedimage.h index 563b0d0095..3b4af7884a 100644 --- a/sdk/android/src/jni/encodedimage.h +++ b/sdk/android/src/jni/encodedimage.h @@ -12,18 +12,21 @@ #define SDK_ANDROID_SRC_JNI_ENCODEDIMAGE_H_ #include - #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 NativeToJavaFrameType(JNIEnv* env, + FrameType frame_type); +ScopedJavaLocalRef NativeToJavaEncodedImage(JNIEnv* jni, + const EncodedImage& image); +ScopedJavaLocalRef NativeToJavaFrameTypeArray( JNIEnv* env, const std::vector& frame_types); diff --git a/sdk/android/src/jni/hardwarevideoencoderfactory.cc b/sdk/android/src/jni/hardwarevideoencoderfactory.cc index baeb426cdf..96e4691f65 100644 --- a/sdk/android/src/jni/hardwarevideoencoderfactory.cc +++ b/sdk/android/src/jni/hardwarevideoencoderfactory.cc @@ -10,20 +10,18 @@ #include -#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&, + const JavaParamRef& params1, + const JavaParamRef& params2) { return H264::IsSameH264Profile(JavaToStdMapStrings(jni, params1), JavaToStdMapStrings(jni, params2)); } diff --git a/sdk/android/src/jni/jni_common.cc b/sdk/android/src/jni/jni_common.cc index 8435c7820d..2d4bbeded3 100644 --- a/sdk/android/src/jni/jni_common.cc +++ b/sdk/android/src/jni/jni_common.cc @@ -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&, + jlong j_native_ref_counted_pointer) { reinterpret_cast(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&, + jlong j_native_ref_counted_pointer) { reinterpret_cast(j_native_ref_counted_pointer) ->Release(); } -JNI_FUNCTION_DECLARATION(jobject, - JniCommon_allocateNativeByteBuffer, - JNIEnv* jni, - jclass, - jint size) { +static ScopedJavaLocalRef JNI_JniCommon_AllocateByteBuffer( + JNIEnv* jni, + const JavaParamRef&, + 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&, + const JavaParamRef& byte_buffer) { + void* data = jni->GetDirectBufferAddress(byte_buffer.obj()); ::operator delete(data); } diff --git a/sdk/android/src/jni/jni_generator_helper.cc b/sdk/android/src/jni/jni_generator_helper.cc index 107144575f..4db7201480 100644 --- a/sdk/android/src/jni/jni_generator_helper.cc +++ b/sdk/android/src/jni/jni_generator_helper.cc @@ -28,22 +28,21 @@ jclass LazyGetClass(JNIEnv* env, rtc::AtomicOps::AcquireLoadPtr(atomic_class_id); if (value) return reinterpret_cast(value); - jclass clazz = static_cast( - env->NewGlobalRef(webrtc::jni::GetClass(env, class_name))); - RTC_CHECK(clazz) << class_name; + webrtc::jni::ScopedJavaGlobalRef 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(clazz)); + reinterpret_cast(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(cas_result); } } diff --git a/sdk/android/src/jni/jni_generator_helper.h b/sdk/android/src/jni/jni_generator_helper.h index 272fcd93d6..6f2cad25cb 100644 --- a/sdk/android/src/jni/jni_generator_helper.h +++ b/sdk/android/src/jni/jni_generator_helper.h @@ -19,6 +19,7 @@ #include #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 -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 -using ScopedJavaLocalRef = JavaRef; -template -using JavaParamRef = JavaRef; +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 diff --git a/sdk/android/src/jni/jni_helpers.cc b/sdk/android/src/jni/jni_helpers.cc index d1bca15bd5..253683fd5f 100644 --- a/sdk/android/src/jni/jni_helpers.cc +++ b/sdk/android/src/jni/jni_helpers.cc @@ -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& obj) { + return jni->IsSameObject(obj.obj(), nullptr); +} + +ScopedJavaLocalRef NewDirectByteBuffer(JNIEnv* env, + void* address, + jlong capacity) { + ScopedJavaLocalRef 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& j_string) { + const ScopedJavaLocalRef 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(&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 JavaToStdVectorStrings(JNIEnv* jni, jobject list) { +std::vector JavaToStdVectorStrings(JNIEnv* jni, + const JavaRef& list) { std::vector converted_list; - if (list != nullptr) { - for (jobject str : Iterable(jni, list)) { - converted_list.push_back( - JavaToStdString(jni, reinterpret_cast(str))); + if (!list.is_null()) { + for (const JavaRef& str : Iterable(jni, list)) { + converted_list.push_back(JavaToStdString( + jni, JavaParamRef(static_cast(str.obj())))); } } return converted_list; } -rtc::Optional JavaToNativeOptionalInt(JNIEnv* jni, jobject integer) { +rtc::Optional JavaToNativeOptionalInt( + JNIEnv* jni, + const JavaRef& integer) { if (IsNull(jni, integer)) return rtc::nullopt; return JNI_Integer::Java_Integer_intValue(jni, integer); } -rtc::Optional JavaToNativeOptionalBool(JNIEnv* jni, jobject boolean) { +rtc::Optional JavaToNativeOptionalBool(JNIEnv* jni, + const JavaRef& 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& j_long) { return JNI_Long::Java_Long_longValue(env, j_long); } -jobject NativeToJavaBoolean(JNIEnv* env, bool b) { +ScopedJavaLocalRef NativeToJavaBoolean(JNIEnv* env, bool b) { return JNI_Boolean::Java_Boolean_ConstructorJLB_Z(env, b); } -jobject NativeToJavaInteger(JNIEnv* jni, int32_t i) { +ScopedJavaLocalRef NativeToJavaInteger(JNIEnv* jni, int32_t i) { return JNI_Integer::Java_Integer_ConstructorJLI_I(jni, i); } -jobject NativeToJavaLong(JNIEnv* env, int64_t u) { +ScopedJavaLocalRef NativeToJavaLong(JNIEnv* env, int64_t u) { return JNI_Long::Java_Long_ConstructorJLLO_J(env, u); } -jobject NativeToJavaDouble(JNIEnv* env, double d) { +ScopedJavaLocalRef 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 NativeToJavaString(JNIEnv* env, const char* str) { + jstring j_str = env->NewStringUTF(str); + CHECK_EXCEPTION(env) << "error during NewStringUTF"; + return ScopedJavaLocalRef(env, j_str); } -jobject NativeToJavaInteger(JNIEnv* jni, - const rtc::Optional& optional_int) { +ScopedJavaLocalRef NativeToJavaString(JNIEnv* jni, + const std::string& str) { + return NativeToJavaString(jni, str.c_str()); +} + +ScopedJavaLocalRef NativeToJavaInteger( + JNIEnv* jni, + const rtc::Optional& 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& j_enum) { return JavaToStdString(jni, JNI_Enum::Java_Enum_name(jni, j_enum)); } -std::map JavaToStdMapStrings(JNIEnv* jni, - jobject j_map) { - jobject j_entry_set = JNI_Map::Java_Map_entrySet(jni, j_map); +std::map JavaToStdMapStrings( + JNIEnv* jni, + const JavaRef& j_map) { + const JavaRef& j_entry_set = JNI_Map::Java_Map_entrySet(jni, j_map); std::map result; - for (jobject j_entry : Iterable(jni, j_entry_set)) { + for (const JavaRef& 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& 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& 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& 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& container) { - jobject (*convert_function)(JNIEnv*, int32_t) = &NativeToJavaInteger; +ScopedJavaLocalRef NativeToJavaIntegerArray( + JNIEnv* env, + const std::vector& container) { + ScopedJavaLocalRef (*convert_function)(JNIEnv*, int32_t) = + &NativeToJavaInteger; return NativeToJavaObjectArray(env, container, java_lang_Integer_clazz(env), convert_function); } -jobjectArray NativeToJavaBooleanArray(JNIEnv* env, - const std::vector& container) { +ScopedJavaLocalRef NativeToJavaBooleanArray( + JNIEnv* env, + const std::vector& container) { return NativeToJavaObjectArray(env, container, java_lang_Boolean_clazz(env), &NativeToJavaBoolean); } -jobjectArray NativeToJavaDoubleArray(JNIEnv* env, - const std::vector& container) { +ScopedJavaLocalRef NativeToJavaDoubleArray( + JNIEnv* env, + const std::vector& container) { return NativeToJavaObjectArray(env, container, java_lang_Double_clazz(env), &NativeToJavaDouble); } -jobjectArray NativeToJavaLongArray(JNIEnv* env, - const std::vector& container) { +ScopedJavaLocalRef NativeToJavaLongArray( + JNIEnv* env, + const std::vector& container) { return NativeToJavaObjectArray(env, container, java_lang_Long_clazz(env), &NativeToJavaLong); } -jobjectArray NativeToJavaStringArray( +ScopedJavaLocalRef NativeToJavaStringArray( JNIEnv* env, const std::vector& container) { + ScopedJavaLocalRef (*convert)(JNIEnv*, const std::string&) = + &NativeToJavaString; return NativeToJavaObjectArray( env, container, - static_cast(Java_JniHelper_getStringClass(env).obj()), - &NativeToJavaString); + static_cast(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& key, + const JavaRef& 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& element) { JNI_ArrayList::Java_ArrayList_addZ_JUE(env_, j_list_, element); } diff --git a/sdk/android/src/jni/jni_helpers.h b/sdk/android/src/jni/jni_helpers.h index 40d9886921..898c47b6b0 100644 --- a/sdk/android/src/jni/jni_helpers.h +++ b/sdk/android/src/jni/jni_helpers.h @@ -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& obj); +ScopedJavaLocalRef 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& j_string); + +// Deprecated. Use scoped jobjects instead. +inline std::string JavaToStdString(JNIEnv* jni, jstring j_string) { + return JavaToStdString(jni, JavaParamRef(j_string)); +} // Given a List of (UTF-16) jstrings // return a new vector of UTF-8 native strings. -std::vector JavaToStdVectorStrings(JNIEnv* jni, jobject list); +std::vector JavaToStdVectorStrings(JNIEnv* jni, + const JavaRef& list); -rtc::Optional JavaToNativeOptionalInt(JNIEnv* jni, jobject integer); -rtc::Optional JavaToNativeOptionalBool(JNIEnv* jni, jobject boolean); -int64_t JavaToNativeLong(JNIEnv* env, jobject j_long); +rtc::Optional JavaToNativeOptionalInt(JNIEnv* jni, + const JavaRef& integer); +rtc::Optional JavaToNativeOptionalBool(JNIEnv* jni, + const JavaRef& boolean); +int64_t JavaToNativeLong(JNIEnv* env, const JavaRef& 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& optional_int); +ScopedJavaLocalRef NativeToJavaBoolean(JNIEnv* env, bool b); +ScopedJavaLocalRef NativeToJavaInteger(JNIEnv* jni, int32_t i); +ScopedJavaLocalRef NativeToJavaLong(JNIEnv* env, int64_t u); +ScopedJavaLocalRef NativeToJavaDouble(JNIEnv* env, double d); +ScopedJavaLocalRef NativeToJavaString(JNIEnv* jni, const char* str); +ScopedJavaLocalRef NativeToJavaString(JNIEnv* jni, + const std::string& str); +ScopedJavaLocalRef NativeToJavaInteger( + JNIEnv* jni, + const rtc::Optional& optional_int); // Parses Map to std::map. -std::map JavaToStdMapStrings(JNIEnv* jni, - jobject j_map); +std::map JavaToStdMapStrings( + JNIEnv* jni, + const JavaRef& j_map); + +// Deprecated. Use scoped jobjects instead. +inline std::map JavaToStdMapStrings(JNIEnv* jni, + jobject j_map) { + return JavaToStdMapStrings(jni, JavaParamRef(j_map)); +} // Returns the name of a Java enum. -std::string GetJavaEnumName(JNIEnv* jni, jobject j_enum); +std::string GetJavaEnumName(JNIEnv* jni, const JavaRef& j_enum); jobject NewGlobalRef(JNIEnv* jni, jobject o); @@ -102,30 +123,6 @@ class ScopedLocalRefFrame { JNIEnv* jni_; }; -// Scoped holder for global Java refs. -template // T is jclass, jobject, jintArray, etc. -class ScopedGlobalRef { - public: - ScopedGlobalRef(JNIEnv* jni, T obj) - : obj_(static_cast(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& 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& 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& operator*(); private: bool AtEnd() const; JNIEnv* jni_ = nullptr; - jobject iterator_ = nullptr; - jobject value_ = nullptr; + ScopedJavaLocalRef iterator_; + ScopedJavaLocalRef value_; rtc::ThreadChecker thread_checker_; RTC_DISALLOW_COPY_AND_ASSIGN(Iterator); @@ -182,52 +182,56 @@ class Iterable { private: JNIEnv* jni_; - jobject iterable_; + ScopedJavaLocalRef iterable_; RTC_DISALLOW_COPY_AND_ASSIGN(Iterable); }; // Helper function for converting std::vector into a Java array. template -jobjectArray NativeToJavaObjectArray(JNIEnv* env, - const std::vector& container, - jclass clazz, - Convert convert) { - jobjectArray j_container = - env->NewObjectArray(container.size(), clazz, nullptr); +ScopedJavaLocalRef NativeToJavaObjectArray( + JNIEnv* env, + const std::vector& container, + jclass clazz, + Convert convert) { + ScopedJavaLocalRef 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& container); -jobjectArray NativeToJavaBooleanArray(JNIEnv* env, - const std::vector& container); -jobjectArray NativeToJavaLongArray(JNIEnv* env, - const std::vector& container); -jobjectArray NativeToJavaDoubleArray(JNIEnv* env, - const std::vector& container); -jobjectArray NativeToJavaStringArray(JNIEnv* env, - const std::vector& container); +ScopedJavaLocalRef NativeToJavaIntegerArray( + JNIEnv* env, + const std::vector& container); +ScopedJavaLocalRef NativeToJavaBooleanArray( + JNIEnv* env, + const std::vector& container); +ScopedJavaLocalRef NativeToJavaLongArray( + JNIEnv* env, + const std::vector& container); +ScopedJavaLocalRef NativeToJavaDoubleArray( + JNIEnv* env, + const std::vector& container); +ScopedJavaLocalRef NativeToJavaStringArray( + JNIEnv* env, + const std::vector& container); template std::vector JavaToNativeVector(JNIEnv* env, - jobjectArray j_container, + const JavaRef& j_container, Convert convert) { std::vector 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( + env, env->GetObjectArrayElement(j_container.obj(), i)))); } CHECK_EXCEPTION(env) << "Error during JavaToNativeVector"; return container; @@ -238,16 +242,19 @@ std::vector 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& element); + ScopedJavaLocalRef java_list() { return j_list_; } private: JNIEnv* env_; - jobject j_list_; + ScopedJavaLocalRef j_list_; }; template -jobject NativeToJavaList(JNIEnv* env, const C& container, Convert convert) { +ScopedJavaLocalRef 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& key, const JavaRef& value); + ScopedJavaLocalRef GetJavaMap() { return j_map_; } private: JNIEnv* env_; - jobject j_map_; + ScopedJavaLocalRef j_map_; }; template -jobject NativeToJavaMap(JNIEnv* env, const C& container, Convert convert) { +ScopedJavaLocalRef NativeToJavaMap(JNIEnv* env, + const C& container, + Convert convert) { JavaMapBuilder builder(env); for (const auto& e : container) { ScopedLocalRefFrame local_ref_frame(env); diff --git a/sdk/android/src/jni/nv12buffer.cc b/sdk/android/src/jni/nv12buffer.cc index bc11b9390c..5f7edc85cf 100644 --- a/sdk/android/src/jni/nv12buffer.cc +++ b/sdk/android/src/jni/nv12buffer.cc @@ -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&, + jint crop_x, + jint crop_y, + jint crop_width, + jint crop_height, + jint scale_width, + jint scale_height, + const JavaParamRef& j_src, + jint src_width, + jint src_height, + jint src_stride, + jint src_slice_height, + const JavaParamRef& j_dst_y, + jint dst_stride_y, + const JavaParamRef& j_dst_u, + jint dst_stride_u, + const JavaParamRef& 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(jni->GetDirectBufferAddress(j_src)); + static_cast(jni->GetDirectBufferAddress(j_src.obj())); uint8_t const* src_uv = src_y + src_slice_height * src_stride_y; - uint8_t* dst_y = static_cast(jni->GetDirectBufferAddress(j_dst_y)); - uint8_t* dst_u = static_cast(jni->GetDirectBufferAddress(j_dst_u)); - uint8_t* dst_v = static_cast(jni->GetDirectBufferAddress(j_dst_v)); + uint8_t* dst_y = + static_cast(jni->GetDirectBufferAddress(j_dst_y.obj())); + uint8_t* dst_u = + static_cast(jni->GetDirectBufferAddress(j_dst_u.obj())); + uint8_t* dst_v = + static_cast(jni->GetDirectBufferAddress(j_dst_v.obj())); // Crop using pointer arithmetic. src_y += crop_x + crop_y * src_stride_y; diff --git a/sdk/android/src/jni/nv21buffer.cc b/sdk/android/src/jni/nv21buffer.cc index 2e107d7cbc..c8a3a8b749 100644 --- a/sdk/android/src/jni/nv21buffer.cc +++ b/sdk/android/src/jni/nv21buffer.cc @@ -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&, + jint crop_x, + jint crop_y, + jint crop_width, + jint crop_height, + jint scale_width, + jint scale_height, + const JavaParamRef& j_src, + jint src_width, + jint src_height, + const JavaParamRef& j_dst_y, + jint dst_stride_y, + const JavaParamRef& j_dst_u, + jint dst_stride_u, + const JavaParamRef& 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(src_bytes); uint8_t const* src_uv = src_y + src_height * src_stride_y; - uint8_t* dst_y = static_cast(jni->GetDirectBufferAddress(j_dst_y)); - uint8_t* dst_u = static_cast(jni->GetDirectBufferAddress(j_dst_u)); - uint8_t* dst_v = static_cast(jni->GetDirectBufferAddress(j_dst_v)); + uint8_t* dst_y = + static_cast(jni->GetDirectBufferAddress(j_dst_y.obj())); + uint8_t* dst_u = + static_cast(jni->GetDirectBufferAddress(j_dst_u.obj())); + uint8_t* dst_v = + static_cast(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 diff --git a/sdk/android/src/jni/pc/androidnetworkmonitor.cc b/sdk/android/src/jni/pc/androidnetworkmonitor.cc index a916e9aca8..5e85c845be 100644 --- a/sdk/android/src/jni/pc/androidnetworkmonitor.cc +++ b/sdk/android/src/jni/pc/androidnetworkmonitor.cc @@ -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& 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& j_ip_address) { + ScopedJavaLocalRef 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& 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 j_ip_addresses = Java_NetworkInformation_getIpAddresses(jni, j_network_info); network_info.ip_addresses = JavaToNativeVector( 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& j_caller) { OnNetworksChanged(); } void AndroidNetworkMonitor::NotifyOfActiveNetworkList( JNIEnv* env, - jobject j_caller, - jobjectArray j_network_infos) { + const JavaRef& j_caller, + const JavaRef& j_network_infos) { std::vector network_infos = JavaToNativeVector(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& j_caller, + const JavaRef& 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& j_caller, + jlong network_handle) { OnNetworkDisconnected(static_cast(network_handle)); } diff --git a/sdk/android/src/jni/pc/androidnetworkmonitor.h b/sdk/android/src/jni/pc/androidnetworkmonitor.h index 6478f83d46..0d99a13e70 100644 --- a/sdk/android/src/jni/pc/androidnetworkmonitor.h +++ b/sdk/android/src/jni/pc/androidnetworkmonitor.h @@ -69,23 +69,24 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorBase, // Always expected to be called on the network thread. void SetNetworkInfos(const std::vector& network_infos); - void NotifyConnectionTypeChanged(JNIEnv* env, jobject j_caller); + void NotifyConnectionTypeChanged(JNIEnv* env, + const JavaRef& j_caller); void NotifyOfNetworkConnect(JNIEnv* env, - jobject j_caller, - jobject j_network_info); + const JavaRef& j_caller, + const JavaRef& j_network_info); void NotifyOfNetworkDisconnect(JNIEnv* env, - jobject j_caller, + const JavaRef& j_caller, jlong network_handle); void NotifyOfActiveNetworkList(JNIEnv* env, - jobject j_caller, - jobjectArray j_network_infos); + const JavaRef& j_caller, + const JavaRef& j_network_infos); private: void OnNetworkConnected_w(const NetworkInformation& network_info); void OnNetworkDisconnected_w(NetworkHandle network_handle); const int android_sdk_int_; - ScopedGlobalRef j_network_monitor_; + ScopedJavaGlobalRef j_network_monitor_; rtc::ThreadChecker thread_checker_; bool started_ = false; std::map adapter_type_by_name_; diff --git a/sdk/android/src/jni/pc/audiotrack.cc b/sdk/android/src/jni/pc/audiotrack.cc index 9662a6872c..90df121350 100644 --- a/sdk/android/src/jni/pc/audiotrack.cc +++ b/sdk/android/src/jni/pc/audiotrack.cc @@ -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&, + jlong j_p, + jdouble volume) { rtc::scoped_refptr source( reinterpret_cast(j_p)->GetSource()); source->SetVolume(volume); diff --git a/sdk/android/src/jni/pc/callsessionfilerotatinglogsink.cc b/sdk/android/src/jni/pc/callsessionfilerotatinglogsink.cc index af142ae31b..858c8a434d 100644 --- a/sdk/android/src/jni/pc/callsessionfilerotatinglogsink.cc +++ b/sdk/android/src/jni/pc/callsessionfilerotatinglogsink.cc @@ -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&, + const JavaParamRef& 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(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&, + jlong j_sink) { rtc::CallSessionFileRotatingLogSink* sink = reinterpret_cast(j_sink); rtc::LogMessage::RemoveLogToStream(sink); delete sink; } -JNI_FUNCTION_DECLARATION(jbyteArray, - CallSessionFileRotatingLogSink_nativeGetLogData, - JNIEnv* jni, - jclass, - jstring j_dirPath) { +static ScopedJavaLocalRef +JNI_CallSessionFileRotatingLogSink_GetLogData( + JNIEnv* jni, + const JavaParamRef&, + const JavaParamRef& j_dirPath) { std::string dir_path = JavaToStdString(jni, j_dirPath); std::unique_ptr 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(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(jni, jni->NewByteArray(0)); } size_t read = 0; std::unique_ptr buffer(static_cast(malloc(log_size))); stream->ReadAll(buffer.get(), log_size, &read, nullptr); - jbyteArray result = jni->NewByteArray(read); - jni->SetByteArrayRegion(result, 0, read, buffer.get()); + ScopedJavaLocalRef result = + ScopedJavaLocalRef(jni, jni->NewByteArray(read)); + jni->SetByteArrayRegion(result.obj(), 0, read, buffer.get()); return result; } diff --git a/sdk/android/src/jni/pc/datachannel.cc b/sdk/android/src/jni/pc/datachannel.cc index c4be431827..6dd2c8e2be 100644 --- a/sdk/android/src/jni/pc/datachannel.cc +++ b/sdk/android/src/jni/pc/datachannel.cc @@ -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& 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 j_observer_global_; + const ScopedJavaGlobalRef j_observer_global_; }; -DataChannelObserverJni::DataChannelObserverJni(JNIEnv* jni, jobject j_observer) +DataChannelObserverJni::DataChannelObserverJni( + JNIEnv* jni, + const JavaRef& 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(buffer.data.data()), buffer.data.size()); - jobject j_buffer = Java_Buffer_Constructor(env, byte_buffer, buffer.binary); - Java_Observer_onMessage(env, *j_observer_global_, j_buffer); + ScopedJavaLocalRef byte_buffer = NewDirectByteBuffer( + env, const_cast(buffer.data.data()), buffer.data.size()); + ScopedJavaLocalRef 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(j_d); +DataChannelInterface* ExtractNativeDC(JNIEnv* jni, + const JavaParamRef& j_dc) { + return reinterpret_cast( + Java_DataChannel_getNativeDataChannel(jni, j_dc)); } } // namespace -DataChannelInit JavaToNativeDataChannelInit(JNIEnv* env, jobject j_init) { +DataChannelInit JavaToNativeDataChannelInit(JNIEnv* env, + const JavaRef& 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 WrapNativeDataChannel( JNIEnv* env, rtc::scoped_refptr 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& j_dc, + const JavaParamRef& j_observer) { auto observer = rtc::MakeUnique(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& j_dc, + jlong native_observer) { ExtractNativeDC(jni, j_dc)->UnregisterObserver(); delete reinterpret_cast(native_observer); } -JNI_FUNCTION_DECLARATION(jstring, - DataChannel_label, - JNIEnv* jni, - jobject j_dc) { +static ScopedJavaLocalRef JNI_DataChannel_Label( + JNIEnv* jni, + const JavaParamRef& 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& j_dc) { int id = ExtractNativeDC(jni, j_dc)->id(); RTC_CHECK_LE(id, std::numeric_limits::max()) << "id overflowed jint!"; return static_cast(id); } -JNI_FUNCTION_DECLARATION(jobject, - DataChannel_state, - JNIEnv* jni, - jobject j_dc) { +static ScopedJavaLocalRef JNI_DataChannel_State( + JNIEnv* jni, + const JavaParamRef& 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& j_dc) { uint64_t buffered_amount = ExtractNativeDC(jni, j_dc)->buffered_amount(); RTC_CHECK_LE(buffered_amount, std::numeric_limits::max()) << "buffered_amount overflowed jlong!"; return static_cast(buffered_amount); } -JNI_FUNCTION_DECLARATION(void, DataChannel_close, JNIEnv* jni, jobject j_dc) { +static void JNI_DataChannel_Close(JNIEnv* jni, + const JavaParamRef& 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& j_dc, + const JavaParamRef& 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; } diff --git a/sdk/android/src/jni/pc/datachannel.h b/sdk/android/src/jni/pc/datachannel.h index 557520af44..c6786f64e7 100644 --- a/sdk/android/src/jni/pc/datachannel.h +++ b/sdk/android/src/jni/pc/datachannel.h @@ -14,10 +14,12 @@ namespace webrtc { namespace jni { -DataChannelInit JavaToNativeDataChannelInit(JNIEnv* env, jobject j_init); +DataChannelInit JavaToNativeDataChannelInit(JNIEnv* env, + const JavaRef& j_init); -jobject WrapNativeDataChannel(JNIEnv* env, - rtc::scoped_refptr channel); +ScopedJavaLocalRef WrapNativeDataChannel( + JNIEnv* env, + rtc::scoped_refptr channel); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/pc/defaultaudioprocessingfactory.cc b/sdk/android/src/jni/pc/defaultaudioprocessingfactory.cc index a0d2c03dda..bc6d6a43ae 100644 --- a/sdk/android/src/jni/pc/defaultaudioprocessingfactory.cc +++ b/sdk/android/src/jni/pc/defaultaudioprocessingfactory.cc @@ -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&, jlong native_post_processor) { std::unique_ptr post_processor( reinterpret_cast(native_post_processor)); diff --git a/sdk/android/src/jni/pc/dtmfsender.cc b/sdk/android/src/jni/pc/dtmfsender.cc index c8d5493d7e..85c0861443 100644 --- a/sdk/android/src/jni/pc/dtmfsender.cc +++ b/sdk/android/src/jni/pc/dtmfsender.cc @@ -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&, + jlong j_dtmf_sender_pointer) { return reinterpret_cast(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&, + jlong j_dtmf_sender_pointer, + const JavaParamRef& tones, + jint duration, + jint inter_tone_gap) { return reinterpret_cast(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 JNI_DtmfSender_Tones( + JNIEnv* jni, + const JavaParamRef&, + jlong j_dtmf_sender_pointer) { return NativeToJavaString( jni, reinterpret_cast(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&, + jlong j_dtmf_sender_pointer) { return reinterpret_cast(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&, + jlong j_dtmf_sender_pointer) { return reinterpret_cast(j_dtmf_sender_pointer) ->inter_tone_gap(); } diff --git a/sdk/android/src/jni/pc/icecandidate.cc b/sdk/android/src/jni/pc/icecandidate.cc index b51cf9f2ab..e13dc70c28 100644 --- a/sdk/android/src/jni/pc/icecandidate.cc +++ b/sdk/android/src/jni/pc/icecandidate.cc @@ -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 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& 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 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 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 NativeToJavaCandidateArray( JNIEnv* jni, const std::vector& candidates) { return NativeToJavaObjectArray(jni, candidates, @@ -74,7 +78,7 @@ jobjectArray NativeToJavaCandidateArray( PeerConnectionInterface::IceTransportsType JavaToNativeIceTransportsType( JNIEnv* jni, - jobject j_ice_transports_type) { + const JavaRef& 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& 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& 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& 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& 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& 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& 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& 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") diff --git a/sdk/android/src/jni/pc/icecandidate.h b/sdk/android/src/jni/pc/icecandidate.h index 2e0bc47ae8..324aaa6130 100644 --- a/sdk/android/src/jni/pc/icecandidate.h +++ b/sdk/android/src/jni/pc/icecandidate.h @@ -24,14 +24,18 @@ namespace webrtc { namespace jni { -cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, jobject j_candidate); +cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, + const JavaRef& j_candidate); -jobject NativeToJavaCandidate(JNIEnv* env, const cricket::Candidate& candidate); +ScopedJavaLocalRef NativeToJavaCandidate( + JNIEnv* env, + const cricket::Candidate& candidate); -jobject NativeToJavaIceCandidate(JNIEnv* env, - const IceCandidateInterface& candidate); +ScopedJavaLocalRef NativeToJavaIceCandidate( + JNIEnv* env, + const IceCandidateInterface& candidate); -jobjectArray NativeToJavaCandidateArray( +ScopedJavaLocalRef NativeToJavaCandidateArray( JNIEnv* jni, const std::vector& candidates); @@ -40,32 +44,36 @@ jobjectArray NativeToJavaCandidateArray( *****************************************************/ PeerConnectionInterface::IceTransportsType JavaToNativeIceTransportsType( JNIEnv* jni, - jobject j_ice_transports_type); + const JavaRef& j_ice_transports_type); PeerConnectionInterface::BundlePolicy JavaToNativeBundlePolicy( JNIEnv* jni, - jobject j_bundle_policy); + const JavaRef& j_bundle_policy); PeerConnectionInterface::RtcpMuxPolicy JavaToNativeRtcpMuxPolicy( JNIEnv* jni, - jobject j_rtcp_mux_policy); + const JavaRef& j_rtcp_mux_policy); PeerConnectionInterface::TcpCandidatePolicy JavaToNativeTcpCandidatePolicy( JNIEnv* jni, - jobject j_tcp_candidate_policy); + const JavaRef& j_tcp_candidate_policy); PeerConnectionInterface::CandidateNetworkPolicy -JavaToNativeCandidateNetworkPolicy(JNIEnv* jni, - jobject j_candidate_network_policy); +JavaToNativeCandidateNetworkPolicy( + JNIEnv* jni, + const JavaRef& j_candidate_network_policy); -rtc::KeyType JavaToNativeKeyType(JNIEnv* jni, jobject j_key_type); +rtc::KeyType JavaToNativeKeyType(JNIEnv* jni, + const JavaRef& j_key_type); PeerConnectionInterface::ContinualGatheringPolicy -JavaToNativeContinualGatheringPolicy(JNIEnv* jni, jobject j_gathering_policy); +JavaToNativeContinualGatheringPolicy( + JNIEnv* jni, + const JavaRef& j_gathering_policy); PeerConnectionInterface::TlsCertPolicy JavaToNativeTlsCertPolicy( JNIEnv* jni, - jobject j_ice_server_tls_cert_policy); + const JavaRef& j_ice_server_tls_cert_policy); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/pc/logging.cc b/sdk/android/src/jni/pc/logging.cc index 75256439f3..5b7511e5f5 100644 --- a/sdk/android/src/jni/pc/logging.cc +++ b/sdk/android/src/jni/pc/logging.cc @@ -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(j_message)); + std::string tag = JavaToStdString(jni, JavaParamRef(j_tag)); RTC_LOG_TAG(static_cast(j_severity), tag) << message; } diff --git a/sdk/android/src/jni/pc/mediaconstraints.cc b/sdk/android/src/jni/pc/mediaconstraints.cc index 554b5aedb6..5df7f5003e 100644 --- a/sdk/android/src/jni/pc/mediaconstraints.cc +++ b/sdk/android/src/jni/pc/mediaconstraints.cc @@ -22,13 +22,12 @@ namespace { // Helper for translating a List> to a Constraints. MediaConstraintsInterface::Constraints PopulateConstraintsFromJavaPairList( JNIEnv* env, - jobject j_list) { + const JavaRef& 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& 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& j_constraints) : mandatory_(PopulateConstraintsFromJavaPairList( env, Java_MediaConstraints_getMandatory(env, j_constraints))), @@ -59,7 +58,7 @@ class MediaConstraintsJni : public MediaConstraintsInterface { std::unique_ptr JavaToNativeMediaConstraints( JNIEnv* env, - jobject j_constraints) { + const JavaRef& j_constraints) { return rtc::MakeUnique(env, j_constraints); } diff --git a/sdk/android/src/jni/pc/mediaconstraints.h b/sdk/android/src/jni/pc/mediaconstraints.h index 599fb6d47d..fea8d9fd43 100644 --- a/sdk/android/src/jni/pc/mediaconstraints.h +++ b/sdk/android/src/jni/pc/mediaconstraints.h @@ -15,13 +15,14 @@ #include #include "api/mediaconstraintsinterface.h" +#include "sdk/android/src/jni/scoped_java_ref.h" namespace webrtc { namespace jni { std::unique_ptr JavaToNativeMediaConstraints( JNIEnv* env, - jobject j_constraints); + const JavaRef& j_constraints); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/pc/mediasource.cc b/sdk/android/src/jni/pc/mediasource.cc index d8f501fd3c..dfd2ff39cb 100644 --- a/sdk/android/src/jni/pc/mediasource.cc +++ b/sdk/android/src/jni/pc/mediasource.cc @@ -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 +JNI_MediaSource_GetState(JNIEnv* jni, const JavaParamRef&, jlong j_p) { return Java_State_fromNativeIndex( jni, reinterpret_cast(j_p)->state()); } diff --git a/sdk/android/src/jni/pc/mediastream.cc b/sdk/android/src/jni/pc/mediastream.cc index 423786f820..b45c93bed3 100644 --- a/sdk/android/src/jni/pc/mediastream.cc +++ b/sdk/android/src/jni/pc/mediastream.cc @@ -27,12 +27,12 @@ JavaMediaStream::JavaMediaStream( observer_(rtc::MakeUnique(media_stream)) { for (rtc::scoped_refptr 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 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&, + jlong pointer, + jlong j_audio_track_pointer) { return reinterpret_cast(pointer)->AddTrack( reinterpret_cast(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&, + jlong pointer, + jlong j_video_track_pointer) { return reinterpret_cast(pointer)->AddTrack( reinterpret_cast(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&, + jlong pointer, + jlong j_audio_track_pointer) { return reinterpret_cast(pointer)->RemoveTrack( reinterpret_cast(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&, + jlong pointer, + jlong j_video_track_pointer) { return reinterpret_cast(pointer)->RemoveTrack( reinterpret_cast(j_video_track_pointer)); } -JNI_FUNCTION_DECLARATION(jstring, - MediaStream_getNativeLabel, - JNIEnv* jni, - jclass, - jlong j_p) { +static ScopedJavaLocalRef +JNI_MediaStream_GetLabel(JNIEnv* jni, const JavaParamRef&, jlong j_p) { return NativeToJavaString( jni, reinterpret_cast(j_p)->label()); } diff --git a/sdk/android/src/jni/pc/mediastream.h b/sdk/android/src/jni/pc/mediastream.h index 24c426cc82..51dfe23939 100644 --- a/sdk/android/src/jni/pc/mediastream.h +++ b/sdk/android/src/jni/pc/mediastream.h @@ -28,7 +28,9 @@ class JavaMediaStream : public sigslot::has_slots<> { rtc::scoped_refptr media_stream); ~JavaMediaStream(); - jobject j_media_stream() { return *j_media_stream_; } + const ScopedJavaGlobalRef& 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 j_media_stream_; + ScopedJavaGlobalRef j_media_stream_; std::unique_ptr observer_; }; diff --git a/sdk/android/src/jni/pc/mediastreamtrack.cc b/sdk/android/src/jni/pc/mediastreamtrack.cc index c8fa0d3616..06c21d3291 100644 --- a/sdk/android/src/jni/pc/mediastreamtrack.cc +++ b/sdk/android/src/jni/pc/mediastreamtrack.cc @@ -17,56 +17,52 @@ namespace webrtc { namespace jni { -jobject NativeToJavaMediaType(JNIEnv* jni, cricket::MediaType media_type) { +ScopedJavaLocalRef 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& j_media_type) { return static_cast( Java_MediaType_getNative(jni, j_media_type)); } -JNI_FUNCTION_DECLARATION(jstring, - MediaStreamTrack_getNativeId, - JNIEnv* jni, - jclass, - jlong j_p) { +static ScopedJavaLocalRef JNI_MediaStreamTrack_GetId( + JNIEnv* jni, + const JavaParamRef&, + jlong j_p) { return NativeToJavaString( jni, reinterpret_cast(j_p)->id()); } -JNI_FUNCTION_DECLARATION(jstring, - MediaStreamTrack_getNativeKind, - JNIEnv* jni, - jclass, - jlong j_p) { +static ScopedJavaLocalRef JNI_MediaStreamTrack_GetKind( + JNIEnv* jni, + const JavaParamRef&, + jlong j_p) { return NativeToJavaString( jni, reinterpret_cast(j_p)->kind()); } -JNI_FUNCTION_DECLARATION(jboolean, - MediaStreamTrack_getNativeEnabled, - JNIEnv* jni, - jclass, - jlong j_p) { +static jboolean JNI_MediaStreamTrack_GetEnabled(JNIEnv* jni, + const JavaParamRef&, + jlong j_p) { return reinterpret_cast(j_p)->enabled(); } -JNI_FUNCTION_DECLARATION(jobject, - MediaStreamTrack_getNativeState, - JNIEnv* jni, - jclass, - jlong j_p) { +static ScopedJavaLocalRef JNI_MediaStreamTrack_GetState( + JNIEnv* jni, + const JavaParamRef&, + jlong j_p) { return Java_State_fromNativeIndex( jni, reinterpret_cast(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&, + jlong j_p, + jboolean enabled) { return reinterpret_cast(j_p)->set_enabled( enabled); } diff --git a/sdk/android/src/jni/pc/mediastreamtrack.h b/sdk/android/src/jni/pc/mediastreamtrack.h index c787720ec7..22950dc687 100644 --- a/sdk/android/src/jni/pc/mediastreamtrack.h +++ b/sdk/android/src/jni/pc/mediastreamtrack.h @@ -14,12 +14,16 @@ #include #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 NativeToJavaMediaType( + JNIEnv* jni, + cricket::MediaType media_type); +cricket::MediaType JavaToNativeMediaType(JNIEnv* jni, + const JavaRef& j_media_type); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/pc/null_video.cc b/sdk/android/src/jni/pc/null_video.cc index ee36c087ad..b3cf5079eb 100644 --- a/sdk/android/src/jni/pc/null_video.cc +++ b/sdk/android/src/jni/pc/null_video.cc @@ -13,13 +13,30 @@ namespace webrtc { namespace jni { -VideoEncoderFactory* CreateVideoEncoderFactory(JNIEnv* jni, - jobject j_encoder_factory) { +VideoEncoderFactory* CreateVideoEncoderFactory( + JNIEnv* jni, + const JavaRef& j_encoder_factory) { return nullptr; } -VideoDecoderFactory* CreateVideoDecoderFactory(JNIEnv* jni, - jobject j_decoder_factory) { +VideoDecoderFactory* CreateVideoDecoderFactory( + JNIEnv* jni, + const JavaRef& j_decoder_factory) { + return nullptr; +} + +void SetEglContext(JNIEnv* env, + cricket::WebRtcVideoEncoderFactory* encoder_factory, + const JavaRef& egl_context) {} +void SetEglContext(JNIEnv* env, + cricket::WebRtcVideoDecoderFactory* decoder_factory, + const JavaRef& egl_context) {} + +void* CreateVideoSource(JNIEnv* env, + rtc::Thread* signaling_thread, + rtc::Thread* worker_thread, + const JavaParamRef& j_surface_texture_helper, + jboolean is_screencast) { return nullptr; } diff --git a/sdk/android/src/jni/pc/peerconnection.cc b/sdk/android/src/jni/pc/peerconnection.cc index dde933d815..ed1598034a 100644 --- a/sdk/android/src/jni/pc/peerconnection.cc +++ b/sdk/android/src/jni/pc/peerconnection.cc @@ -56,27 +56,32 @@ namespace jni { namespace { -PeerConnectionInterface* ExtractNativePC(JNIEnv* jni, jobject j_pc) { +PeerConnectionInterface* ExtractNativePC(JNIEnv* jni, + const JavaRef& j_pc) { return reinterpret_cast( Java_PeerConnection_getNativePeerConnection(jni, j_pc)); } PeerConnectionInterface::IceServers JavaToNativeIceServers( JNIEnv* jni, - jobject j_ice_servers) { + const JavaRef& 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& j_ice_server : Iterable(jni, j_ice_servers)) { + ScopedJavaLocalRef 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 urls = + Java_IceServer_getUrls(jni, j_ice_server); + ScopedJavaLocalRef username = + Java_IceServer_getUsername(jni, j_ice_server); + ScopedJavaLocalRef 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 hostname = + Java_IceServer_getHostname(jni, j_ice_server); + ScopedJavaLocalRef tls_alpn_protocols = Java_IceServer_getTlsAlpnProtocols(jni, j_ice_server); - jobject tls_elliptic_curves = + ScopedJavaLocalRef 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& j_rtc_config, PeerConnectionInterface::RTCConfiguration* rtc_config) { - jobject j_ice_transports_type = + ScopedJavaLocalRef j_ice_transports_type = Java_RTCConfiguration_getIceTransportsType(jni, j_rtc_config); - jobject j_bundle_policy = + ScopedJavaLocalRef j_bundle_policy = Java_RTCConfiguration_getBundlePolicy(jni, j_rtc_config); - jobject j_rtcp_mux_policy = + ScopedJavaLocalRef j_rtcp_mux_policy = Java_RTCConfiguration_getRtcpMuxPolicy(jni, j_rtc_config); - jobject j_tcp_candidate_policy = + ScopedJavaLocalRef j_tcp_candidate_policy = Java_RTCConfiguration_getTcpCandidatePolicy(jni, j_rtc_config); - jobject j_candidate_network_policy = + ScopedJavaLocalRef j_candidate_network_policy = Java_RTCConfiguration_getCandidateNetworkPolicy(jni, j_rtc_config); - jobject j_ice_servers = + ScopedJavaLocalRef j_ice_servers = Java_RTCConfiguration_getIceServers(jni, j_rtc_config); - jobject j_continual_gathering_policy = + ScopedJavaLocalRef j_continual_gathering_policy = Java_RTCConfiguration_getContinualGatheringPolicy(jni, j_rtc_config); - jobject j_turn_customizer = + ScopedJavaLocalRef 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 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 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& 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& 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& 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 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 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 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 receiver, const std::vector>& streams) { JNIEnv* env = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(env); - jobject j_rtp_receiver = NativeToJavaRtpReceiver(env, receiver); + ScopedJavaLocalRef 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 +PeerConnectionObserverJni::NativeToJavaMediaStreamArray( JNIEnv* jni, const std::vector>& 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 stream) + -> const ScopedJavaGlobalRef& { + 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&, + const JavaParamRef& 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&, + jlong j_p) { PeerConnectionObserverJni* p = reinterpret_cast(j_p); delete p; } -JNI_FUNCTION_DECLARATION(jobject, - PeerConnection_getLocalDescription, - JNIEnv* jni, - jobject j_pc) { +static ScopedJavaLocalRef JNI_PeerConnection_GetLocalDescription( + JNIEnv* jni, + const JavaParamRef& 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 JNI_PeerConnection_GetRemoteDescription( + JNIEnv* jni, + const JavaParamRef& 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 JNI_PeerConnection_CreateDataChannel( + JNIEnv* jni, + const JavaParamRef& j_pc, + const JavaParamRef& j_label, + const JavaParamRef& j_init) { DataChannelInit init = JavaToNativeDataChannelInit(jni, j_init); rtc::scoped_refptr 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& j_pc, + const JavaParamRef& j_observer, + const JavaParamRef& j_constraints) { std::unique_ptr constraints = JavaToNativeMediaConstraints(jni, j_constraints); rtc::scoped_refptr 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& j_pc, + const JavaParamRef& j_observer, + const JavaParamRef& j_constraints) { std::unique_ptr constraints = JavaToNativeMediaConstraints(jni, j_constraints); rtc::scoped_refptr 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& j_pc, + const JavaParamRef& j_observer, + const JavaParamRef& j_sdp) { rtc::scoped_refptr observer( new rtc::RefCountedObject(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& j_pc, + const JavaParamRef& j_observer, + const JavaParamRef& j_sdp) { rtc::scoped_refptr observer( new rtc::RefCountedObject(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& 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& 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& j_pc, + const JavaParamRef& 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& j_pc, + const JavaParamRef& j_sdp_mid, + jint j_sdp_mline_index, + const JavaParamRef& j_candidate_sdp) { std::string sdp_mid = JavaToStdString(jni, j_sdp_mid); std::string sdp = JavaToStdString(jni, j_candidate_sdp); std::unique_ptr 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& j_pc, + const JavaParamRef& j_candidates) { std::vector candidates = JavaToNativeVector(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& j_pc, + jlong native_stream) { return ExtractNativePC(jni, j_pc)->AddStream( reinterpret_cast(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& j_pc, + jlong native_stream) { ExtractNativePC(jni, j_pc)->RemoveStream( reinterpret_cast(native_stream)); } -JNI_FUNCTION_DECLARATION(jobject, - PeerConnection_createNativeSender, - JNIEnv* jni, - jobject j_pc, - jstring j_kind, - jstring j_stream_id) { +static ScopedJavaLocalRef JNI_PeerConnection_CreateSender( + JNIEnv* jni, + const JavaParamRef& j_pc, + const JavaParamRef& j_kind, + const JavaParamRef& j_stream_id) { std::string kind = JavaToStdString(jni, j_kind); std::string stream_id = JavaToStdString(jni, j_stream_id); rtc::scoped_refptr 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 JNI_PeerConnection_GetSenders( + JNIEnv* jni, + const JavaParamRef& j_pc) { return NativeToJavaList(jni, ExtractNativePC(jni, j_pc)->GetSenders(), &NativeToJavaRtpSender); } -JNI_FUNCTION_DECLARATION(jobject, - PeerConnection_getNativeReceivers, - JNIEnv* jni, - jobject j_pc) { +static ScopedJavaLocalRef JNI_PeerConnection_GetReceivers( + JNIEnv* jni, + const JavaParamRef& 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& j_pc, + const JavaParamRef& j_observer, + jlong native_track) { rtc::scoped_refptr observer( new rtc::RefCountedObject(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& j_pc, + const JavaParamRef& j_callback) { rtc::scoped_refptr callback( new rtc::RefCountedObject(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& j_pc, + const JavaParamRef& j_min, + const JavaParamRef& j_current, + const JavaParamRef& 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& 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& j_pc) { ExtractNativePC(jni, j_pc)->StopRtcEventLog(); } -JNI_FUNCTION_DECLARATION(jobject, - PeerConnection_signalingState, - JNIEnv* env, - jobject j_pc) { +static ScopedJavaLocalRef JNI_PeerConnection_SignalingState( + JNIEnv* env, + const JavaParamRef& 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 JNI_PeerConnection_IceConnectionState( + JNIEnv* env, + const JavaParamRef& 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 JNI_PeerConnection_IceGatheringState( + JNIEnv* env, + const JavaParamRef& 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& j_pc) { ExtractNativePC(jni, j_pc)->Close(); } diff --git a/sdk/android/src/jni/pc/peerconnection.h b/sdk/android/src/jni/pc/peerconnection.h index 2afc109bd4..7e14b51306 100644 --- a/sdk/android/src/jni/pc/peerconnection.h +++ b/sdk/android/src/jni/pc/peerconnection.h @@ -27,17 +27,18 @@ namespace jni { void JavaToNativeRTCConfiguration( JNIEnv* jni, - jobject j_rtc_config, + const JavaRef& j_rtc_config, PeerConnectionInterface::RTCConfiguration* rtc_config); -rtc::KeyType GetRtcConfigKeyType(JNIEnv* env, jobject j_rtc_config); +rtc::KeyType GetRtcConfigKeyType(JNIEnv* env, + const JavaRef& 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& j_observer); virtual ~PeerConnectionObserverJni(); // Implementation of PeerConnectionObserver interface, which propagates @@ -76,11 +77,11 @@ class PeerConnectionObserverJni : public PeerConnectionObserver { const rtc::scoped_refptr& stream); // Converts array of streams, creating or re-using Java streams as necessary. - jobjectArray NativeToJavaMediaStreamArray( + ScopedJavaLocalRef NativeToJavaMediaStreamArray( JNIEnv* jni, const std::vector>& streams); - const ScopedGlobalRef j_observer_global_; + const ScopedJavaGlobalRef j_observer_global_; // C++ -> Java remote streams. NativeToJavaStreamsMap remote_streams_; diff --git a/sdk/android/src/jni/pc/peerconnectionfactory.cc b/sdk/android/src/jni/pc/peerconnectionfactory.cc index c5a16b6206..b625df8401 100644 --- a/sdk/android/src/jni/pc/peerconnectionfactory.cc +++ b/sdk/android/src/jni/pc/peerconnectionfactory.cc @@ -45,7 +45,8 @@ namespace jni { namespace { PeerConnectionFactoryInterface::Options -JavaToNativePeerConnectionFactoryOptions(JNIEnv* jni, jobject options) { +JavaToNativePeerConnectionFactoryOptions(JNIEnv* jni, + const JavaRef& 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&, + const JavaParamRef& 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&, + const JavaParamRef& 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&) { rtc::tracing::SetupInternalTracer(); } -JNI_FUNCTION_DECLARATION(jstring, - PeerConnectionFactory_findNativeFieldTrialsFullName, - JNIEnv* jni, - jclass, - jstring j_name) { +static ScopedJavaLocalRef +JNI_PeerConnectionFactory_FindFieldTrialsFullName( + JNIEnv* jni, + const JavaParamRef&, + const JavaParamRef& 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&, + const JavaParamRef& 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&) { rtc::tracing::StopInternalCapture(); } -JNI_FUNCTION_DECLARATION(void, - PeerConnectionFactory_shutdownNativeInternalTracer, - JNIEnv* jni, - jclass) { +static void JNI_PeerConnectionFactory_ShutdownInternalTracer( + JNIEnv* jni, + const JavaParamRef&) { rtc::tracing::ShutdownInternalTracer(); } jlong CreatePeerConnectionFactoryForJava( JNIEnv* jni, - jobject joptions, - jobject jencoder_factory, - jobject jdecoder_factory, + const JavaParamRef& joptions, + const JavaParamRef& jencoder_factory, + const JavaParamRef& jdecoder_factory, rtc::scoped_refptr 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 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 video_encoder_factory = nullptr; - if (jencoder_factory == nullptr) { + if (jencoder_factory.is_null()) { legacy_video_encoder_factory = CreateLegacyVideoEncoderFactory(); video_encoder_factory = std::unique_ptr( WrapLegacyVideoEncoderFactory(legacy_video_encoder_factory)); @@ -246,7 +242,7 @@ jlong CreatePeerConnectionFactoryForJava( } std::unique_ptr video_decoder_factory = nullptr; - if (jdecoder_factory == nullptr) { + if (jdecoder_factory.is_null()) { legacy_video_decoder_factory = CreateLegacyVideoDecoderFactory(); video_decoder_factory = std::unique_ptr( 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&, + const JavaParamRef& joptions, + const JavaParamRef& jencoder_factory, + const JavaParamRef& 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&, + const JavaParamRef& joptions, + const JavaParamRef& jencoder_factory, + const JavaParamRef& jdecoder_factory, jlong native_audio_processor) { rtc::scoped_refptr audio_processor = reinterpret_cast(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&, + jlong j_p) { delete reinterpret_cast(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&, + jlong j_p) { OwnedFactoryAndThreads* factory = reinterpret_cast(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&, + jlong native_factory, + const JavaParamRef& label) { rtc::scoped_refptr factory( factoryFromJava(native_factory)); rtc::scoped_refptr 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&, + jlong native_factory, + const JavaParamRef& j_constraints) { std::unique_ptr constraints = JavaToNativeMediaConstraints(jni, j_constraints); rtc::scoped_refptr factory( @@ -361,52 +349,47 @@ JNI_FUNCTION_DECLARATION(jlong, CopyConstraintsIntoAudioOptions(constraints.get(), &options); rtc::scoped_refptr 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&, + jlong native_factory, + const JavaParamRef& id, + jlong native_source) { rtc::scoped_refptr factory( factoryFromJava(native_factory)); rtc::scoped_refptr track(factory->CreateAudioTrack( JavaToStdString(jni, id), reinterpret_cast(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&, + jlong native_factory, + jint file, + jint filesize_limit_bytes) { rtc::scoped_refptr 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&, + jlong native_factory) { rtc::scoped_refptr 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&, + jlong native_factory, + const JavaParamRef& options) { rtc::scoped_refptr 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&, + jlong factory, + const JavaParamRef& j_rtc_config, + const JavaParamRef& j_constraints, + jlong observer_p) { rtc::scoped_refptr f( reinterpret_cast( factoryFromJava(factory))); @@ -456,7 +438,7 @@ JNI_FUNCTION_DECLARATION(jlong, PeerConnectionObserverJni* observer = reinterpret_cast(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&, + jlong native_factory, + const JavaParamRef& j_surface_texture_helper, + jboolean is_screencast) { OwnedFactoryAndThreads* factory = reinterpret_cast(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&, + jlong native_factory, + const JavaParamRef& id, + jlong native_source) { rtc::scoped_refptr factory( factoryFromJava(native_factory)); rtc::scoped_refptr 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&, jlong native_factory, - jobject local_egl_context, - jobject remote_egl_context) { + const JavaParamRef& local_egl_context, + const JavaParamRef& remote_egl_context) { OwnedFactoryAndThreads* owned_factory = reinterpret_cast(native_factory); SetEglContext(jni, owned_factory->legacy_encoder_factory(), diff --git a/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.cc b/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.cc index 196cb701f0..c61f37c4e4 100644 --- a/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.cc +++ b/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.cc @@ -24,19 +24,21 @@ namespace jni { namespace { -jobject NativeToJavaBigInteger(JNIEnv* env, uint64_t u) { +ScopedJavaLocalRef NativeToJavaBigInteger(JNIEnv* env, uint64_t u) { return JNI_BigInteger::Java_BigInteger_ConstructorJMBI_JLS( env, NativeToJavaString(env, rtc::ToString(u))); } -jobjectArray NativeToJavaBigIntegerArray( +ScopedJavaLocalRef NativeToJavaBigIntegerArray( JNIEnv* env, const std::vector& container) { return NativeToJavaObjectArray( env, container, java_math_BigInteger_clazz(env), &NativeToJavaBigInteger); } -jobject MemberToJava(JNIEnv* env, const RTCStatsMemberInterface& member) { +ScopedJavaLocalRef MemberToJava( + JNIEnv* env, + const RTCStatsMemberInterface& member) { switch (member.type()) { case RTCStatsMemberInterface::kBool: return NativeToJavaBoolean(env, *member.cast_to>()); @@ -96,12 +98,12 @@ jobject MemberToJava(JNIEnv* env, const RTCStatsMemberInterface& member) { return nullptr; } -jobject NativeToJavaRtcStats(JNIEnv* env, const RTCStats& stats) { +ScopedJavaLocalRef 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 NativeToJavaRtcStatsReport( JNIEnv* env, const rtc::scoped_refptr& report) { - jobject j_stats_map = + ScopedJavaLocalRef 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& j_callback) : j_callback_global_(jni, j_callback) {} void RTCStatsCollectorCallbackWrapper::OnStatsDelivered( const rtc::scoped_refptr& 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 diff --git a/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.h b/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.h index ffda94a978..7fd7585ce9 100644 --- a/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.h +++ b/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.h @@ -24,13 +24,14 @@ namespace jni { // Java. class RTCStatsCollectorCallbackWrapper : public RTCStatsCollectorCallback { public: - RTCStatsCollectorCallbackWrapper(JNIEnv* jni, jobject j_callback); + RTCStatsCollectorCallbackWrapper(JNIEnv* jni, + const JavaRef& j_callback); void OnStatsDelivered( const rtc::scoped_refptr& report) override; private: - const ScopedGlobalRef j_callback_global_; + const ScopedJavaGlobalRef j_callback_global_; }; } // namespace jni diff --git a/sdk/android/src/jni/pc/rtpparameters.cc b/sdk/android/src/jni/pc/rtpparameters.cc index 904d410d09..e9082e61cf 100644 --- a/sdk/android/src/jni/pc/rtpparameters.cc +++ b/sdk/android/src/jni/pc/rtpparameters.cc @@ -19,7 +19,7 @@ namespace jni { namespace { -jobject NativeToJavaRtpEncodingParameter( +ScopedJavaLocalRef 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 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& 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 j_encodings = + Java_RtpParameters_getEncodings(jni, j_parameters); + for (const JavaRef& j_encoding_parameters : + Iterable(jni, j_encodings)) { RtpEncodingParameters encoding; encoding.active = Java_Encoding_getActive(jni, j_encoding_parameters); - jobject j_bitrate = + ScopedJavaLocalRef 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 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 j_codecs = + Java_RtpParameters_getCodecs(jni, j_parameters); + for (const JavaRef& 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 NativeToJavaRtpParameters( + JNIEnv* env, + const RtpParameters& parameters) { return Java_RtpParameters_Constructor( env, NativeToJavaList(env, parameters.encodings, diff --git a/sdk/android/src/jni/pc/rtpparameters.h b/sdk/android/src/jni/pc/rtpparameters.h index b704b90910..7de4bde8f4 100644 --- a/sdk/android/src/jni/pc/rtpparameters.h +++ b/sdk/android/src/jni/pc/rtpparameters.h @@ -14,12 +14,16 @@ #include #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& j_parameters); +ScopedJavaLocalRef NativeToJavaRtpParameters( + JNIEnv* jni, + const RtpParameters& parameters); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/pc/rtpreceiver.cc b/sdk/android/src/jni/pc/rtpreceiver.cc index 714e5c8a97..c96ac930d8 100644 --- a/sdk/android/src/jni/pc/rtpreceiver.cc +++ b/sdk/android/src/jni/pc/rtpreceiver.cc @@ -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& 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 j_observer_global_; + const ScopedJavaGlobalRef j_observer_global_; }; } // namespace -jobject NativeToJavaRtpReceiver( +ScopedJavaLocalRef NativeToJavaRtpReceiver( JNIEnv* env, rtc::scoped_refptr 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& 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&, + jlong j_rtp_receiver_pointer) { return jlongFromPointer( reinterpret_cast(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&, + jlong j_rtp_receiver_pointer, + const JavaParamRef& j_parameters) { RtpParameters parameters = JavaToNativeRtpParameters(jni, j_parameters); return reinterpret_cast(j_rtp_receiver_pointer) ->SetParameters(parameters); } -JNI_FUNCTION_DECLARATION(jobject, - RtpReceiver_getNativeParameters, - JNIEnv* jni, - jclass, - jlong j_rtp_receiver_pointer) { +static ScopedJavaLocalRef JNI_RtpReceiver_GetParameters( + JNIEnv* jni, + const JavaParamRef&, + jlong j_rtp_receiver_pointer) { RtpParameters parameters = reinterpret_cast(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 JNI_RtpReceiver_GetId( + JNIEnv* jni, + const JavaParamRef&, + jlong j_rtp_receiver_pointer) { return NativeToJavaString( jni, reinterpret_cast(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&, + jlong j_rtp_receiver_pointer, + const JavaParamRef& j_observer) { RtpReceiverObserverJni* rtpReceiverObserver = new RtpReceiverObserverJni(jni, j_observer); reinterpret_cast(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&, + jlong j_rtp_receiver_pointer, + jlong j_observer_pointer) { reinterpret_cast(j_rtp_receiver_pointer) ->SetObserver(nullptr); RtpReceiverObserverJni* observer = diff --git a/sdk/android/src/jni/pc/rtpreceiver.h b/sdk/android/src/jni/pc/rtpreceiver.h index ec87d7c46c..f7688ee066 100644 --- a/sdk/android/src/jni/pc/rtpreceiver.h +++ b/sdk/android/src/jni/pc/rtpreceiver.h @@ -14,12 +14,12 @@ #include #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 NativeToJavaRtpReceiver( JNIEnv* env, rtc::scoped_refptr 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& j_receiver); JavaRtpReceiverGlobalOwner(JavaRtpReceiverGlobalOwner&& other); ~JavaRtpReceiverGlobalOwner(); private: - ScopedGlobalRef j_receiver_; + ScopedJavaGlobalRef j_receiver_; }; } // namespace jni diff --git a/sdk/android/src/jni/pc/rtpsender.cc b/sdk/android/src/jni/pc/rtpsender.cc index 6099fcbd7b..da59ad017a 100644 --- a/sdk/android/src/jni/pc/rtpsender.cc +++ b/sdk/android/src/jni/pc/rtpsender.cc @@ -17,8 +17,9 @@ namespace webrtc { namespace jni { -jobject NativeToJavaRtpSender(JNIEnv* env, - rtc::scoped_refptr sender) { +ScopedJavaLocalRef NativeToJavaRtpSender( + JNIEnv* env, + rtc::scoped_refptr 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&, + jlong j_rtp_sender_pointer, + jlong j_track_pointer) { return reinterpret_cast(j_rtp_sender_pointer) ->SetTrack(reinterpret_cast(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&, + jlong j_rtp_sender_pointer) { return jlongFromPointer( reinterpret_cast(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&, + jlong j_rtp_sender_pointer) { return jlongFromPointer( reinterpret_cast(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&, + jlong j_rtp_sender_pointer, + const JavaParamRef& 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 JNI_RtpSender_GetParameters( + JNIEnv* jni, + const JavaParamRef&, + jlong j_rtp_sender_pointer) { RtpParameters parameters = reinterpret_cast(j_rtp_sender_pointer) ->GetParameters(); return NativeToJavaRtpParameters(jni, parameters); } -JNI_FUNCTION_DECLARATION(jstring, - RtpSender_getNativeId, - JNIEnv* jni, - jclass, - jlong j_rtp_sender_pointer) { +ScopedJavaLocalRef JNI_RtpSender_GetId(JNIEnv* jni, + const JavaParamRef&, + jlong j_rtp_sender_pointer) { return NativeToJavaString( jni, reinterpret_cast(j_rtp_sender_pointer)->id()); } diff --git a/sdk/android/src/jni/pc/rtpsender.h b/sdk/android/src/jni/pc/rtpsender.h index 5f7e1b8e6c..a11c012f49 100644 --- a/sdk/android/src/jni/pc/rtpsender.h +++ b/sdk/android/src/jni/pc/rtpsender.h @@ -14,12 +14,14 @@ #include #include "api/rtpsenderinterface.h" +#include "sdk/android/src/jni/scoped_java_ref.h" namespace webrtc { namespace jni { -jobject NativeToJavaRtpSender(JNIEnv* env, - rtc::scoped_refptr sender); +ScopedJavaLocalRef NativeToJavaRtpSender( + JNIEnv* env, + rtc::scoped_refptr sender); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/pc/sdpobserver.cc b/sdk/android/src/jni/pc/sdpobserver.cc index 54bf8d038a..59d8eac591 100644 --- a/sdk/android/src/jni/pc/sdpobserver.cc +++ b/sdk/android/src/jni/pc/sdpobserver.cc @@ -21,15 +21,14 @@ namespace jni { CreateSdpObserverJni::CreateSdpObserverJni( JNIEnv* env, - jobject j_observer, + const JavaRef& j_observer, std::unique_ptr 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& j_observer, std::unique_ptr 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)); } diff --git a/sdk/android/src/jni/pc/sdpobserver.h b/sdk/android/src/jni/pc/sdpobserver.h index 79a5a99fb9..ec8befe573 100644 --- a/sdk/android/src/jni/pc/sdpobserver.h +++ b/sdk/android/src/jni/pc/sdpobserver.h @@ -24,7 +24,7 @@ namespace jni { class CreateSdpObserverJni : public CreateSessionDescriptionObserver { public: CreateSdpObserverJni(JNIEnv* env, - jobject j_observer, + const JavaRef& j_observer, std::unique_ptr constraints); MediaConstraintsInterface* constraints() { return constraints_.get(); } @@ -33,14 +33,14 @@ class CreateSdpObserverJni : public CreateSessionDescriptionObserver { void OnFailure(const std::string& error) override; private: - const ScopedGlobalRef j_observer_global_; + const ScopedJavaGlobalRef j_observer_global_; std::unique_ptr constraints_; }; class SetSdpObserverJni : public SetSessionDescriptionObserver { public: SetSdpObserverJni(JNIEnv* env, - jobject j_observer, + const JavaRef& j_observer, std::unique_ptr constraints); MediaConstraintsInterface* constraints() { return constraints_.get(); } @@ -49,7 +49,7 @@ class SetSdpObserverJni : public SetSessionDescriptionObserver { void OnFailure(const std::string& error) override; private: - const ScopedGlobalRef j_observer_global_; + const ScopedJavaGlobalRef j_observer_global_; std::unique_ptr constraints_; }; diff --git a/sdk/android/src/jni/pc/sessiondescription.cc b/sdk/android/src/jni/pc/sessiondescription.cc index 1b6d6c1186..43354ce8c0 100644 --- a/sdk/android/src/jni/pc/sessiondescription.cc +++ b/sdk/android/src/jni/pc/sessiondescription.cc @@ -21,7 +21,7 @@ namespace jni { std::unique_ptr JavaToNativeSessionDescription( JNIEnv* jni, - jobject j_sdp) { + const JavaRef& 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 JavaToNativeSessionDescription( return CreateSessionDescription(*sdp_type_maybe, std_description); } -jobject NativeToJavaSessionDescription( +ScopedJavaLocalRef 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 diff --git a/sdk/android/src/jni/pc/sessiondescription.h b/sdk/android/src/jni/pc/sessiondescription.h index 9e54783665..57d563e10e 100644 --- a/sdk/android/src/jni/pc/sessiondescription.h +++ b/sdk/android/src/jni/pc/sessiondescription.h @@ -15,16 +15,18 @@ #include #include "api/jsep.h" +#include "sdk/android/src/jni/scoped_java_ref.h" namespace webrtc { namespace jni { std::unique_ptr JavaToNativeSessionDescription( JNIEnv* jni, - jobject j_sdp); + const JavaRef& j_sdp); -jobject NativeToJavaSessionDescription(JNIEnv* jni, - const SessionDescriptionInterface* desc); +ScopedJavaLocalRef NativeToJavaSessionDescription( + JNIEnv* jni, + const SessionDescriptionInterface* desc); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/pc/statsobserver.cc b/sdk/android/src/jni/pc/statsobserver.cc index 24d0759950..56718de773 100644 --- a/sdk/android/src/jni/pc/statsobserver.cc +++ b/sdk/android/src/jni/pc/statsobserver.cc @@ -21,20 +21,17 @@ namespace jni { namespace { -jobject NativeToJavaStatsReportValue( +ScopedJavaLocalRef NativeToJavaStatsReportValue( JNIEnv* env, const rtc::scoped_refptr& 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 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 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& j_observer) : j_observer_global_(jni, j_observer) {} void StatsObserverJni::OnComplete(const StatsReports& reports) { JNIEnv* env = AttachCurrentThreadIfNeeded(); - jobjectArray j_reports = + ScopedJavaLocalRef 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 diff --git a/sdk/android/src/jni/pc/statsobserver.h b/sdk/android/src/jni/pc/statsobserver.h index 0579905d62..6ef14ac208 100644 --- a/sdk/android/src/jni/pc/statsobserver.h +++ b/sdk/android/src/jni/pc/statsobserver.h @@ -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& j_observer); void OnComplete(const StatsReports& reports) override; private: - const ScopedGlobalRef j_observer_global_; + const ScopedJavaGlobalRef j_observer_global_; }; } // namespace jni diff --git a/sdk/android/src/jni/pc/turncustomizer.cc b/sdk/android/src/jni/pc/turncustomizer.cc index a220664c8e..8d48e12a1f 100644 --- a/sdk/android/src/jni/pc/turncustomizer.cc +++ b/sdk/android/src/jni/pc/turncustomizer.cc @@ -15,19 +15,19 @@ namespace webrtc { namespace jni { -TurnCustomizer* GetNativeTurnCustomizer(JNIEnv* env, - jobject j_turn_customizer) { +TurnCustomizer* GetNativeTurnCustomizer( + JNIEnv* env, + const JavaRef& j_turn_customizer) { if (IsNull(env, j_turn_customizer)) return nullptr; return reinterpret_cast( 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&, + jlong j_turn_customizer_pointer) { delete reinterpret_cast(j_turn_customizer_pointer); } diff --git a/sdk/android/src/jni/pc/turncustomizer.h b/sdk/android/src/jni/pc/turncustomizer.h index 2484227c32..ed4a3d5b7e 100644 --- a/sdk/android/src/jni/pc/turncustomizer.h +++ b/sdk/android/src/jni/pc/turncustomizer.h @@ -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& j_turn_customizer); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/pc/video.cc b/sdk/android/src/jni/pc/video.cc index cda3238da5..55379f7944 100644 --- a/sdk/android/src/jni/pc/video.cc +++ b/sdk/android/src/jni/pc/video.cc @@ -32,38 +32,40 @@ namespace webrtc { namespace jni { -VideoEncoderFactory* CreateVideoEncoderFactory(JNIEnv* jni, - jobject j_encoder_factory) { +VideoEncoderFactory* CreateVideoEncoderFactory( + JNIEnv* jni, + const JavaRef& j_encoder_factory) { return new VideoEncoderFactoryWrapper(jni, j_encoder_factory); } -VideoDecoderFactory* CreateVideoDecoderFactory(JNIEnv* jni, - jobject j_decoder_factory) { +VideoDecoderFactory* CreateVideoDecoderFactory( + JNIEnv* jni, + const JavaRef& j_decoder_factory) { return new VideoDecoderFactoryWrapper(jni, j_decoder_factory); } void SetEglContext(JNIEnv* env, cricket::WebRtcVideoEncoderFactory* encoder_factory, - jobject egl_context) { + const JavaRef& egl_context) { if (encoder_factory) { MediaCodecVideoEncoderFactory* media_codec_factory = static_cast(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& egl_context) { if (decoder_factory) { MediaCodecVideoDecoderFactory* media_codec_factory = static_cast(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& j_surface_texture_helper, jboolean is_screencast) { rtc::scoped_refptr source( new rtc::RefCountedObject( diff --git a/sdk/android/src/jni/pc/video.h b/sdk/android/src/jni/pc/video.h index a05e172a56..0fd7ac2939 100644 --- a/sdk/android/src/jni/pc/video.h +++ b/sdk/android/src/jni/pc/video.h @@ -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& j_encoder_factory); -VideoDecoderFactory* CreateVideoDecoderFactory(JNIEnv* jni, - jobject j_decoder_factory); +VideoDecoderFactory* CreateVideoDecoderFactory( + JNIEnv* jni, + const JavaRef& j_decoder_factory); void SetEglContext(JNIEnv* env, cricket::WebRtcVideoEncoderFactory* encoder_factory, - jobject egl_context); + const JavaRef& egl_context); void SetEglContext(JNIEnv* env, cricket::WebRtcVideoDecoderFactory* decoder_factory, - jobject egl_context); + const JavaRef& egl_context); void* CreateVideoSource(JNIEnv* env, rtc::Thread* signaling_thread, rtc::Thread* worker_thread, - jobject j_surface_texture_helper, + const JavaParamRef& j_surface_texture_helper, jboolean is_screencast); cricket::WebRtcVideoEncoderFactory* CreateLegacyVideoEncoderFactory(); diff --git a/sdk/android/src/jni/scoped_java_ref.h b/sdk/android/src/jni/scoped_java_ref.h new file mode 100644 index 0000000000..8fac4b34f3 --- /dev/null +++ b/sdk/android/src/jni/scoped_java_ref.h @@ -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 +#include + +#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 +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 +// into a function taking const JavaRef&. +template <> +class JavaRef { + 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 +class JavaRef : public JavaRef { + public: + T obj() const { return static_cast(obj_); } + + protected: + JavaRef() : JavaRef(nullptr) {} + explicit JavaRef(T obj) : JavaRef(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 in the JNI binding generator. Do not create +// instances manually. +template +class JavaParamRef : public JavaRef { + 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(obj) {} + JavaParamRef(JNIEnv*, T obj) : JavaRef(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 +class ScopedJavaLocalRef : public JavaRef { + public: + ScopedJavaLocalRef() = default; + ScopedJavaLocalRef(std::nullptr_t) {} // NOLINT(runtime/explicit) + + ScopedJavaLocalRef(JNIEnv* env, const JavaRef& other) : env_(env) { + Reset(other.obj(), OwnershipPolicy::RETAIN); + } + // Allow constructing e.g. ScopedJavaLocalRef from + // ScopedJavaLocalRef. + template + ScopedJavaLocalRef(ScopedJavaLocalRef&& 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(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(obj_); + obj_ = nullptr; + return obj; + } + + JNIEnv* env() const { return env_; } + + private: + using JavaRef::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 +class ScopedJavaGlobalRef : public JavaRef { + public: + using JavaRef::obj_; + + ScopedJavaGlobalRef(JNIEnv* env, const JavaRef& other) + : JavaRef(static_cast(env->NewGlobalRef(other.obj()))) {} + explicit ScopedJavaGlobalRef(const ScopedJavaLocalRef& other) + : ScopedJavaGlobalRef(other.env(), other) {} + ScopedJavaGlobalRef(ScopedJavaGlobalRef&& other) + : JavaRef(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(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_ diff --git a/sdk/android/src/jni/surfacetexturehelper.cc b/sdk/android/src/jni/surfacetexturehelper.cc index 190fb2d06c..3c6b7c0d24 100644 --- a/sdk/android/src/jni/surfacetexturehelper.cc +++ b/sdk/android/src/jni/surfacetexturehelper.cc @@ -18,13 +18,14 @@ namespace webrtc { namespace jni { -void SurfaceTextureHelperTextureToYUV(JNIEnv* env, - jobject j_surface_texture_helper, - jobject buffer, - int width, - int height, - int stride, - const NativeHandleImpl& native_handle) { +void SurfaceTextureHelperTextureToYUV( + JNIEnv* env, + const JavaRef& j_surface_texture_helper, + const JavaRef& buffer, + int width, + int height, + int stride, + const NativeHandleImpl& native_handle) { Java_SurfaceTextureHelper_textureToYUV( env, j_surface_texture_helper, buffer, width, height, stride, native_handle.oes_texture_id, native_handle.sampling_matrix.ToJava(env)); @@ -33,34 +34,35 @@ void SurfaceTextureHelperTextureToYUV(JNIEnv* env, rtc::scoped_refptr SurfaceTextureHelper::create( JNIEnv* jni, const char* thread_name, - jobject j_egl_context) { - jobject j_surface_texture_helper = Java_SurfaceTextureHelper_create( - jni, NativeToJavaString(jni, thread_name), j_egl_context); - CHECK_EXCEPTION(jni) - << "error during initialization of Java SurfaceTextureHelper"; + const JavaRef& j_egl_context) { + ScopedJavaLocalRef j_surface_texture_helper = + Java_SurfaceTextureHelper_create( + jni, NativeToJavaString(jni, thread_name), j_egl_context); if (IsNull(jni, j_surface_texture_helper)) return nullptr; return new rtc::RefCountedObject( jni, j_surface_texture_helper); } -SurfaceTextureHelper::SurfaceTextureHelper(JNIEnv* jni, - jobject j_surface_texture_helper) +SurfaceTextureHelper::SurfaceTextureHelper( + JNIEnv* jni, + const JavaRef& j_surface_texture_helper) : j_surface_texture_helper_(jni, j_surface_texture_helper) {} SurfaceTextureHelper::~SurfaceTextureHelper() { RTC_LOG(LS_INFO) << "SurfaceTextureHelper dtor"; JNIEnv* jni = AttachCurrentThreadIfNeeded(); - Java_SurfaceTextureHelper_dispose(jni, *j_surface_texture_helper_); + Java_SurfaceTextureHelper_dispose(jni, j_surface_texture_helper_); } -jobject SurfaceTextureHelper::GetJavaSurfaceTextureHelper() const { - return *j_surface_texture_helper_; +const ScopedJavaGlobalRef& +SurfaceTextureHelper::GetJavaSurfaceTextureHelper() const { + return j_surface_texture_helper_; } void SurfaceTextureHelper::ReturnTextureFrame() const { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - Java_SurfaceTextureHelper_returnTextureFrame(jni, *j_surface_texture_helper_); + Java_SurfaceTextureHelper_returnTextureFrame(jni, j_surface_texture_helper_); } rtc::scoped_refptr SurfaceTextureHelper::CreateTextureFrame( diff --git a/sdk/android/src/jni/surfacetexturehelper.h b/sdk/android/src/jni/surfacetexturehelper.h index 1909b8fb39..d1cf3b5059 100644 --- a/sdk/android/src/jni/surfacetexturehelper.h +++ b/sdk/android/src/jni/surfacetexturehelper.h @@ -43,10 +43,12 @@ struct NativeHandleImpl; class SurfaceTextureHelper : public rtc::RefCountInterface { public: // Might return null if creating the Java SurfaceTextureHelper fails. - static rtc::scoped_refptr - create(JNIEnv* jni, const char* thread_name, jobject j_egl_context); + static rtc::scoped_refptr create( + JNIEnv* jni, + const char* thread_name, + const JavaRef& j_egl_context); - jobject GetJavaSurfaceTextureHelper() const; + const ScopedJavaGlobalRef& GetJavaSurfaceTextureHelper() const; rtc::scoped_refptr CreateTextureFrame( int width, @@ -58,19 +60,21 @@ class SurfaceTextureHelper : public rtc::RefCountInterface { protected: ~SurfaceTextureHelper(); - SurfaceTextureHelper(JNIEnv* jni, jobject j_surface_texture_helper); + SurfaceTextureHelper(JNIEnv* jni, + const JavaRef& j_surface_texture_helper); private: - const ScopedGlobalRef j_surface_texture_helper_; + const ScopedJavaGlobalRef j_surface_texture_helper_; }; -void SurfaceTextureHelperTextureToYUV(JNIEnv* env, - jobject j_surface_texture_helper, - jobject buffer, - int width, - int height, - int stride, - const NativeHandleImpl& native_handle); +void SurfaceTextureHelperTextureToYUV( + JNIEnv* env, + const JavaRef& j_surface_texture_helper, + const JavaRef& buffer, + int width, + int height, + int stride, + const NativeHandleImpl& native_handle); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/video_renderer.cc b/sdk/android/src/jni/video_renderer.cc index 8be76a81e6..674a8ddfab 100644 --- a/sdk/android/src/jni/video_renderer.cc +++ b/sdk/android/src/jni/video_renderer.cc @@ -23,16 +23,15 @@ namespace jni { // instance. class JavaVideoRendererWrapper : public rtc::VideoSinkInterface { public: - JavaVideoRendererWrapper(JNIEnv* jni, jobject j_callbacks) + JavaVideoRendererWrapper(JNIEnv* jni, const JavaRef& j_callbacks) : j_callbacks_(jni, j_callbacks) {} virtual ~JavaVideoRendererWrapper() {} void OnFrame(const VideoFrame& video_frame) override { JNIEnv* env = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(env); - jobject j_frame; + ScopedJavaLocalRef j_frame; if (video_frame.video_frame_buffer()->type() == VideoFrameBuffer::Type::kNative) { AndroidVideoFrameBuffer* android_buffer = @@ -53,7 +52,7 @@ class JavaVideoRendererWrapper : public rtc::VideoSinkInterface { } // |j_callbacks_| is responsible for releasing |j_frame| with // VideoRenderer.renderFrameDone(). - Java_Callbacks_renderFrame(env, *j_callbacks_, j_frame); + Java_Callbacks_renderFrame(env, j_callbacks_, j_frame); } private: @@ -65,7 +64,8 @@ class JavaVideoRendererWrapper : public rtc::VideoSinkInterface { } // Return a VideoRenderer.I420Frame referring to the data in |frame|. - jobject FromWrappedJavaBuffer(JNIEnv* env, const VideoFrame& frame) { + ScopedJavaLocalRef FromWrappedJavaBuffer(JNIEnv* env, + const VideoFrame& frame) { return Java_I420Frame_Constructor( env, frame.rotation(), static_cast(frame.video_frame_buffer().get()) @@ -74,19 +74,20 @@ class JavaVideoRendererWrapper : public rtc::VideoSinkInterface { } // Return a VideoRenderer.I420Frame referring to the data in |frame|. - jobject ToJavaI420Frame(JNIEnv* env, const VideoFrame& frame) { + ScopedJavaLocalRef ToJavaI420Frame(JNIEnv* env, + const VideoFrame& frame) { rtc::scoped_refptr i420_buffer = frame.video_frame_buffer()->ToI420(); - jobject y_buffer = env->NewDirectByteBuffer( - const_cast(i420_buffer->DataY()), - i420_buffer->StrideY() * i420_buffer->height()); + ScopedJavaLocalRef y_buffer = + NewDirectByteBuffer(env, const_cast(i420_buffer->DataY()), + i420_buffer->StrideY() * i420_buffer->height()); size_t chroma_height = i420_buffer->ChromaHeight(); - jobject u_buffer = - env->NewDirectByteBuffer(const_cast(i420_buffer->DataU()), - i420_buffer->StrideU() * chroma_height); - jobject v_buffer = - env->NewDirectByteBuffer(const_cast(i420_buffer->DataV()), - i420_buffer->StrideV() * chroma_height); + ScopedJavaLocalRef u_buffer = + NewDirectByteBuffer(env, const_cast(i420_buffer->DataU()), + i420_buffer->StrideU() * chroma_height); + ScopedJavaLocalRef v_buffer = + NewDirectByteBuffer(env, const_cast(i420_buffer->DataV()), + i420_buffer->StrideV() * chroma_height); return Java_I420Frame_createI420Frame( env, frame.width(), frame.height(), static_cast(frame.rotation()), i420_buffer->StrideY(), y_buffer, i420_buffer->StrideU(), u_buffer, @@ -94,68 +95,63 @@ class JavaVideoRendererWrapper : public rtc::VideoSinkInterface { } // Return a VideoRenderer.I420Frame referring texture object in |frame|. - jobject ToJavaTextureFrame(JNIEnv* env, const VideoFrame& frame) { + ScopedJavaLocalRef ToJavaTextureFrame(JNIEnv* env, + const VideoFrame& frame) { NativeHandleImpl handle = static_cast(frame.video_frame_buffer().get()) ->native_handle_impl(); - jfloatArray sampling_matrix = handle.sampling_matrix.ToJava(env); - return Java_I420Frame_createTextureFrame( env, frame.width(), frame.height(), static_cast(frame.rotation()), - handle.oes_texture_id, sampling_matrix, javaShallowCopy(frame)); + handle.oes_texture_id, handle.sampling_matrix.ToJava(env), + javaShallowCopy(frame)); } - ScopedGlobalRef j_callbacks_; + ScopedJavaGlobalRef j_callbacks_; }; -JNI_FUNCTION_DECLARATION(void, - VideoRenderer_freeWrappedVideoRenderer, - JNIEnv*, - jclass, - jlong j_p) { +static void JNI_VideoRenderer_FreeWrappedVideoRenderer( + JNIEnv*, + const JavaParamRef&, + jlong j_p) { delete reinterpret_cast(j_p); } -JNI_FUNCTION_DECLARATION(void, - VideoRenderer_releaseNativeFrame, - JNIEnv* jni, - jclass, - jlong j_frame_ptr) { +static void JNI_VideoRenderer_ReleaseFrame(JNIEnv* jni, + const JavaParamRef&, + jlong j_frame_ptr) { delete reinterpret_cast(j_frame_ptr); } -JNI_FUNCTION_DECLARATION(jlong, - VideoRenderer_createNativeVideoRenderer, - JNIEnv* jni, - jclass, - jobject j_callbacks) { +static jlong JNI_VideoRenderer_CreateVideoRenderer( + JNIEnv* jni, + const JavaParamRef&, + const JavaParamRef& j_callbacks) { std::unique_ptr renderer( new JavaVideoRendererWrapper(jni, j_callbacks)); return jlongFromPointer(renderer.release()); } -JNI_FUNCTION_DECLARATION(void, - VideoRenderer_copyPlaneNative, - JNIEnv* jni, - jclass, - jobject j_src_buffer, - jint width, - jint height, - jint src_stride, - jobject j_dst_buffer, - jint dst_stride) { - size_t src_size = jni->GetDirectBufferCapacity(j_src_buffer); - size_t dst_size = jni->GetDirectBufferCapacity(j_dst_buffer); +static void JNI_VideoRenderer_CopyPlane( + JNIEnv* jni, + const JavaParamRef&, + const JavaParamRef& j_src_buffer, + jint width, + jint height, + jint src_stride, + const JavaParamRef& j_dst_buffer, + jint dst_stride) { + size_t src_size = jni->GetDirectBufferCapacity(j_src_buffer.obj()); + size_t dst_size = jni->GetDirectBufferCapacity(j_dst_buffer.obj()); RTC_CHECK(src_stride >= width) << "Wrong source stride " << src_stride; RTC_CHECK(dst_stride >= width) << "Wrong destination stride " << dst_stride; RTC_CHECK(src_size >= src_stride * height) << "Insufficient source buffer capacity " << src_size; RTC_CHECK(dst_size >= dst_stride * height) << "Insufficient destination buffer capacity " << dst_size; - uint8_t* src = - reinterpret_cast(jni->GetDirectBufferAddress(j_src_buffer)); - uint8_t* dst = - reinterpret_cast(jni->GetDirectBufferAddress(j_dst_buffer)); + uint8_t* src = reinterpret_cast( + jni->GetDirectBufferAddress(j_src_buffer.obj())); + uint8_t* dst = reinterpret_cast( + jni->GetDirectBufferAddress(j_dst_buffer.obj())); if (src_stride == dst_stride) { memcpy(dst, src, src_stride * height); } else { diff --git a/sdk/android/src/jni/videocodecinfo.cc b/sdk/android/src/jni/videocodecinfo.cc index 50a6394054..c21e38ea3c 100644 --- a/sdk/android/src/jni/videocodecinfo.cc +++ b/sdk/android/src/jni/videocodecinfo.cc @@ -16,15 +16,17 @@ namespace webrtc { namespace jni { -SdpVideoFormat VideoCodecInfoToSdpVideoFormat(JNIEnv* jni, jobject j_info) { +SdpVideoFormat VideoCodecInfoToSdpVideoFormat(JNIEnv* jni, + const JavaRef& j_info) { return SdpVideoFormat( JavaToStdString(jni, Java_VideoCodecInfo_getName(jni, j_info)), JavaToStdMapStrings(jni, Java_VideoCodecInfo_getParams(jni, j_info))); } -jobject SdpVideoFormatToVideoCodecInfo(JNIEnv* jni, - const SdpVideoFormat& format) { - jobject j_params = NativeToJavaMap( +ScopedJavaLocalRef SdpVideoFormatToVideoCodecInfo( + JNIEnv* jni, + const SdpVideoFormat& format) { + ScopedJavaLocalRef j_params = NativeToJavaMap( jni, format.parameters, [](JNIEnv* env, const std::pair& entry) { return std::make_pair(NativeToJavaString(env, entry.first), diff --git a/sdk/android/src/jni/videocodecinfo.h b/sdk/android/src/jni/videocodecinfo.h index ea72273a55..2829c02b07 100644 --- a/sdk/android/src/jni/videocodecinfo.h +++ b/sdk/android/src/jni/videocodecinfo.h @@ -14,13 +14,16 @@ #include #include "api/video_codecs/sdp_video_format.h" +#include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { namespace jni { -SdpVideoFormat VideoCodecInfoToSdpVideoFormat(JNIEnv* jni, jobject info); -jobject SdpVideoFormatToVideoCodecInfo(JNIEnv* jni, - const SdpVideoFormat& format); +SdpVideoFormat VideoCodecInfoToSdpVideoFormat(JNIEnv* jni, + const JavaRef& info); +ScopedJavaLocalRef SdpVideoFormatToVideoCodecInfo( + JNIEnv* jni, + const SdpVideoFormat& format); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/videocodecstatus.cc b/sdk/android/src/jni/videocodecstatus.cc index 6641f30ac4..b4a0a525f2 100644 --- a/sdk/android/src/jni/videocodecstatus.cc +++ b/sdk/android/src/jni/videocodecstatus.cc @@ -15,8 +15,9 @@ namespace webrtc { namespace jni { -int32_t JavaToNativeVideoCodecStatus(JNIEnv* env, - jobject j_video_codec_status) { +int32_t JavaToNativeVideoCodecStatus( + JNIEnv* env, + const JavaRef& j_video_codec_status) { return Java_VideoCodecStatus_getNumber(env, j_video_codec_status); } diff --git a/sdk/android/src/jni/videocodecstatus.h b/sdk/android/src/jni/videocodecstatus.h index a2ad39ed73..bfcdbe5307 100644 --- a/sdk/android/src/jni/videocodecstatus.h +++ b/sdk/android/src/jni/videocodecstatus.h @@ -14,9 +14,13 @@ #include #include +#include "sdk/android/src/jni/scoped_java_ref.h" + namespace webrtc { namespace jni { -int32_t JavaToNativeVideoCodecStatus(JNIEnv* env, jobject j_video_codec_status); +int32_t JavaToNativeVideoCodecStatus( + JNIEnv* env, + const JavaRef& j_video_codec_status); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/videodecoderfactorywrapper.cc b/sdk/android/src/jni/videodecoderfactorywrapper.cc index 1adabc015b..f41ef40f55 100644 --- a/sdk/android/src/jni/videodecoderfactorywrapper.cc +++ b/sdk/android/src/jni/videodecoderfactorywrapper.cc @@ -20,17 +20,19 @@ namespace webrtc { namespace jni { -VideoDecoderFactoryWrapper::VideoDecoderFactoryWrapper(JNIEnv* jni, - jobject decoder_factory) +VideoDecoderFactoryWrapper::VideoDecoderFactoryWrapper( + JNIEnv* jni, + const JavaRef& decoder_factory) : decoder_factory_(jni, decoder_factory) {} std::unique_ptr VideoDecoderFactoryWrapper::CreateVideoDecoder( const SdpVideoFormat& format) { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(jni); - jobject decoder = Java_VideoDecoderFactory_createDecoder( - jni, *decoder_factory_, NativeToJavaString(jni, format.name)); - return decoder != nullptr ? JavaToNativeVideoDecoder(jni, decoder) : nullptr; + ScopedJavaLocalRef decoder = Java_VideoDecoderFactory_createDecoder( + jni, decoder_factory_, NativeToJavaString(jni, format.name)); + if (!decoder.obj()) + return nullptr; + return JavaToNativeVideoDecoder(jni, decoder); } std::vector VideoDecoderFactoryWrapper::GetSupportedFormats() diff --git a/sdk/android/src/jni/videodecoderfactorywrapper.h b/sdk/android/src/jni/videodecoderfactorywrapper.h index a02181af47..49ac849f93 100644 --- a/sdk/android/src/jni/videodecoderfactorywrapper.h +++ b/sdk/android/src/jni/videodecoderfactorywrapper.h @@ -23,14 +23,15 @@ namespace jni { // JNI and wraps the decoder inside VideoDecoderWrapper. class VideoDecoderFactoryWrapper : public VideoDecoderFactory { public: - VideoDecoderFactoryWrapper(JNIEnv* jni, jobject decoder_factory); + VideoDecoderFactoryWrapper(JNIEnv* jni, + const JavaRef& decoder_factory); std::vector GetSupportedFormats() const override; std::unique_ptr CreateVideoDecoder( const SdpVideoFormat& format) override; private: - const ScopedGlobalRef decoder_factory_; + const ScopedJavaGlobalRef decoder_factory_; }; } // namespace jni diff --git a/sdk/android/src/jni/videodecoderfallback.cc b/sdk/android/src/jni/videodecoderfallback.cc index 92ad6ad9a5..6d09c776a5 100644 --- a/sdk/android/src/jni/videodecoderfallback.cc +++ b/sdk/android/src/jni/videodecoderfallback.cc @@ -11,18 +11,18 @@ #include #include "media/engine/videodecodersoftwarefallbackwrapper.h" +#include "sdk/android/generated_video_jni/jni/VideoDecoderFallback_jni.h" #include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/wrappednativecodec.h" namespace webrtc { namespace jni { -JNI_FUNCTION_DECLARATION(jlong, - VideoDecoderFallback_createNativeDecoder, - JNIEnv* jni, - jclass, - jobject j_fallback_decoder, - jobject j_primary_decoder) { +static jlong JNI_VideoDecoderFallback_CreateDecoder( + JNIEnv* jni, + const JavaParamRef&, + const JavaParamRef& j_fallback_decoder, + const JavaParamRef& j_primary_decoder) { std::unique_ptr fallback_decoder = JavaToNativeVideoDecoder(jni, j_fallback_decoder); std::unique_ptr primary_decoder = diff --git a/sdk/android/src/jni/videodecoderwrapper.cc b/sdk/android/src/jni/videodecoderwrapper.cc index 9776df569f..85c62f944b 100644 --- a/sdk/android/src/jni/videodecoderwrapper.cc +++ b/sdk/android/src/jni/videodecoderwrapper.cc @@ -35,7 +35,8 @@ inline rtc::Optional cast_optional(const rtc::Optional& value) { } } // namespace -VideoDecoderWrapper::VideoDecoderWrapper(JNIEnv* jni, jobject decoder) +VideoDecoderWrapper::VideoDecoderWrapper(JNIEnv* jni, + const JavaRef& decoder) : decoder_(jni, decoder) { initialized_ = false; // QP parsing starts enabled and we disable it if the decoder provides frames. @@ -48,22 +49,21 @@ VideoDecoderWrapper::VideoDecoderWrapper(JNIEnv* jni, jobject decoder) int32_t VideoDecoderWrapper::InitDecode(const VideoCodec* codec_settings, int32_t number_of_cores) { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(jni); - codec_settings_ = *codec_settings; number_of_cores_ = number_of_cores; return InitDecodeInternal(jni); } int32_t VideoDecoderWrapper::InitDecodeInternal(JNIEnv* jni) { - jobject settings = Java_Settings_Constructor( + ScopedJavaLocalRef settings = Java_Settings_Constructor( jni, number_of_cores_, codec_settings_.width, codec_settings_.height); - jobject callback = Java_VideoDecoderWrapper_createDecoderCallback( - jni, jlongFromPointer(this)); + ScopedJavaLocalRef callback = + Java_VideoDecoderWrapper_createDecoderCallback(jni, + jlongFromPointer(this)); - jobject ret = - Java_VideoDecoder_initDecode(jni, *decoder_, settings, callback); + ScopedJavaLocalRef ret = + Java_VideoDecoder_initDecode(jni, decoder_, settings, callback); if (JavaToNativeVideoCodecStatus(jni, ret) == WEBRTC_VIDEO_CODEC_OK) { initialized_ = true; } @@ -86,9 +86,6 @@ int32_t VideoDecoderWrapper::Decode( return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; } - JNIEnv* jni = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(jni); - // Make a mutable copy so we can modify the timestamp. EncodedImage input_image(image_param); // We use RTP timestamp for capture time because capture_time_ms_ is always 0. @@ -104,9 +101,13 @@ int32_t VideoDecoderWrapper::Decode( qp_parsing_enabled_ ? ParseQP(input_image) : rtc::nullopt; frame_extra_infos_.push_back(frame_extra_info); - jobject jinput_image = NativeToJavaEncodedImage(jni, input_image); - jobject ret = Java_VideoDecoder_decode(jni, *decoder_, jinput_image, nullptr); - return HandleReturnCode(jni, ret); + JNIEnv* env = AttachCurrentThreadIfNeeded(); + ScopedJavaLocalRef jinput_image = + NativeToJavaEncodedImage(env, input_image); + ScopedJavaLocalRef decode_info; + ScopedJavaLocalRef ret = + Java_VideoDecoder_decode(env, decoder_, jinput_image, decode_info); + return HandleReturnCode(env, ret); } int32_t VideoDecoderWrapper::RegisterDecodeCompleteCallback( @@ -117,8 +118,7 @@ int32_t VideoDecoderWrapper::RegisterDecodeCompleteCallback( int32_t VideoDecoderWrapper::Release() { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(jni); - jobject ret = Java_VideoDecoder_release(jni, *decoder_); + ScopedJavaLocalRef ret = Java_VideoDecoder_release(jni, decoder_); frame_extra_infos_.clear(); initialized_ = false; return HandleReturnCode(jni, ret); @@ -126,18 +126,19 @@ int32_t VideoDecoderWrapper::Release() { bool VideoDecoderWrapper::PrefersLateDecoding() const { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - return Java_VideoDecoder_getPrefersLateDecoding(jni, *decoder_); + return Java_VideoDecoder_getPrefersLateDecoding(jni, decoder_); } const char* VideoDecoderWrapper::ImplementationName() const { return implementation_name_.c_str(); } -void VideoDecoderWrapper::OnDecodedFrame(JNIEnv* env, - jobject j_caller, - jobject j_frame, - jobject j_decode_time_ms, - jobject j_qp) { +void VideoDecoderWrapper::OnDecodedFrame( + JNIEnv* env, + const JavaRef& j_caller, + const JavaRef& j_frame, + const JavaRef& j_decode_time_ms, + const JavaRef& j_qp) { const uint64_t timestamp_ns = GetJavaVideoFrameTimestampNs(env, j_frame); FrameExtraInfo frame_extra_info; @@ -170,7 +171,8 @@ void VideoDecoderWrapper::OnDecodedFrame(JNIEnv* env, decoder_qp ? decoder_qp : frame_extra_info.qp); } -int32_t VideoDecoderWrapper::HandleReturnCode(JNIEnv* jni, jobject code) { +int32_t VideoDecoderWrapper::HandleReturnCode(JNIEnv* jni, + const JavaRef& code) { int32_t value = JavaToNativeVideoCodecStatus(jni, code); if (value < 0) { // Any errors are represented by negative values. // Reset the codec. diff --git a/sdk/android/src/jni/videodecoderwrapper.h b/sdk/android/src/jni/videodecoderwrapper.h index 14ced839e7..09dcb448ea 100644 --- a/sdk/android/src/jni/videodecoderwrapper.h +++ b/sdk/android/src/jni/videodecoderwrapper.h @@ -24,7 +24,7 @@ namespace jni { // Wraps a Java decoder and delegates all calls to it. class VideoDecoderWrapper : public VideoDecoder { public: - VideoDecoderWrapper(JNIEnv* jni, jobject decoder); + VideoDecoderWrapper(JNIEnv* jni, const JavaRef& decoder); int32_t InitDecode(const VideoCodec* codec_settings, int32_t number_of_cores) override; @@ -49,10 +49,10 @@ class VideoDecoderWrapper : public VideoDecoder { // Wraps the frame to a AndroidVideoBuffer and passes it to the callback. void OnDecodedFrame(JNIEnv* env, - jobject j_caller, - jobject j_frame, - jobject j_decode_time_ms, - jobject j_qp); + const JavaRef& j_caller, + const JavaRef& j_frame, + const JavaRef& j_decode_time_ms, + const JavaRef& j_qp); private: struct FrameExtraInfo { @@ -67,7 +67,7 @@ class VideoDecoderWrapper : public VideoDecoder { // Takes Java VideoCodecStatus, handles it and returns WEBRTC_VIDEO_CODEC_* // status code. - int32_t HandleReturnCode(JNIEnv* jni, jobject code); + int32_t HandleReturnCode(JNIEnv* jni, const JavaRef& code); rtc::Optional ParseQP(const EncodedImage& input_image); @@ -82,7 +82,7 @@ class VideoDecoderWrapper : public VideoDecoder { DecodedImageCallback* callback_; - const ScopedGlobalRef decoder_; + const ScopedJavaGlobalRef decoder_; }; } // namespace jni diff --git a/sdk/android/src/jni/videoencoderfactorywrapper.cc b/sdk/android/src/jni/videoencoderfactorywrapper.cc index 834490af47..328e6fdeb5 100644 --- a/sdk/android/src/jni/videoencoderfactorywrapper.cc +++ b/sdk/android/src/jni/videoencoderfactorywrapper.cc @@ -21,10 +21,11 @@ namespace webrtc { namespace jni { -VideoEncoderFactoryWrapper::VideoEncoderFactoryWrapper(JNIEnv* jni, - jobject encoder_factory) +VideoEncoderFactoryWrapper::VideoEncoderFactoryWrapper( + JNIEnv* jni, + const JavaRef& encoder_factory) : encoder_factory_(jni, encoder_factory) { - const jobjectArray j_supported_codecs = + const ScopedJavaLocalRef j_supported_codecs = Java_VideoEncoderFactory_getSupportedCodecs(jni, encoder_factory); supported_formats_ = JavaToNativeVector( jni, j_supported_codecs, &VideoCodecInfoToSdpVideoFormat); @@ -33,21 +34,22 @@ VideoEncoderFactoryWrapper::VideoEncoderFactoryWrapper(JNIEnv* jni, std::unique_ptr VideoEncoderFactoryWrapper::CreateVideoEncoder( const SdpVideoFormat& format) { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(jni); - jobject j_codec_info = SdpVideoFormatToVideoCodecInfo(jni, format); - jobject encoder = Java_VideoEncoderFactory_createEncoder( - jni, *encoder_factory_, j_codec_info); - return encoder != nullptr ? JavaToNativeVideoEncoder(jni, encoder) : nullptr; + ScopedJavaLocalRef j_codec_info = + SdpVideoFormatToVideoCodecInfo(jni, format); + ScopedJavaLocalRef encoder = Java_VideoEncoderFactory_createEncoder( + jni, encoder_factory_, j_codec_info); + if (!encoder.obj()) + return nullptr; + return JavaToNativeVideoEncoder(jni, encoder); } VideoEncoderFactory::CodecInfo VideoEncoderFactoryWrapper::QueryVideoEncoder( const SdpVideoFormat& format) const { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(jni); - - jobject j_codec_info = SdpVideoFormatToVideoCodecInfo(jni, format); - jobject encoder = Java_VideoEncoderFactory_createEncoder( - jni, *encoder_factory_, j_codec_info); + ScopedJavaLocalRef j_codec_info = + SdpVideoFormatToVideoCodecInfo(jni, format); + ScopedJavaLocalRef encoder = Java_VideoEncoderFactory_createEncoder( + jni, encoder_factory_, j_codec_info); CodecInfo codec_info; // Check if this is a wrapped native software encoder implementation. diff --git a/sdk/android/src/jni/videoencoderfactorywrapper.h b/sdk/android/src/jni/videoencoderfactorywrapper.h index cd7787fe9a..af9557cf9c 100644 --- a/sdk/android/src/jni/videoencoderfactorywrapper.h +++ b/sdk/android/src/jni/videoencoderfactorywrapper.h @@ -25,7 +25,8 @@ namespace jni { // JNI and wraps the encoder inside VideoEncoderWrapper. class VideoEncoderFactoryWrapper : public VideoEncoderFactory { public: - VideoEncoderFactoryWrapper(JNIEnv* jni, jobject encoder_factory); + VideoEncoderFactoryWrapper(JNIEnv* jni, + const JavaRef& encoder_factory); std::unique_ptr CreateVideoEncoder( const SdpVideoFormat& format) override; @@ -38,7 +39,7 @@ class VideoEncoderFactoryWrapper : public VideoEncoderFactory { CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override; private: - const ScopedGlobalRef encoder_factory_; + const ScopedJavaGlobalRef encoder_factory_; std::vector supported_formats_; }; diff --git a/sdk/android/src/jni/videoencoderfallback.cc b/sdk/android/src/jni/videoencoderfallback.cc index b151f15fed..086a3a9688 100644 --- a/sdk/android/src/jni/videoencoderfallback.cc +++ b/sdk/android/src/jni/videoencoderfallback.cc @@ -11,18 +11,18 @@ #include #include "media/engine/videoencodersoftwarefallbackwrapper.h" +#include "sdk/android/generated_video_jni/jni/VideoEncoderFallback_jni.h" #include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/wrappednativecodec.h" namespace webrtc { namespace jni { -JNI_FUNCTION_DECLARATION(jlong, - VideoEncoderFallback_createNativeEncoder, - JNIEnv* jni, - jclass, - jobject j_fallback_encoder, - jobject j_primary_encoder) { +static jlong JNI_VideoEncoderFallback_CreateEncoder( + JNIEnv* jni, + const JavaParamRef&, + const JavaParamRef& j_fallback_encoder, + const JavaParamRef& j_primary_encoder) { std::unique_ptr fallback_encoder = JavaToNativeVideoEncoder(jni, j_fallback_encoder); std::unique_ptr primary_encoder = diff --git a/sdk/android/src/jni/videoencoderwrapper.cc b/sdk/android/src/jni/videoencoderwrapper.cc index f2cbde94bc..125a97cc9a 100644 --- a/sdk/android/src/jni/videoencoderwrapper.cc +++ b/sdk/android/src/jni/videoencoderwrapper.cc @@ -32,9 +32,9 @@ namespace jni { static const int kMaxJavaEncoderResets = 3; -VideoEncoderWrapper::VideoEncoderWrapper(JNIEnv* jni, jobject j_encoder) - : encoder_(jni, j_encoder), - int_array_class_(jni, jni->FindClass("[I")) { +VideoEncoderWrapper::VideoEncoderWrapper(JNIEnv* jni, + const JavaRef& j_encoder) + : encoder_(jni, j_encoder), int_array_class_(GetClass(jni, "[I")) { implementation_name_ = GetImplementationName(jni); initialized_ = false; @@ -49,7 +49,6 @@ int32_t VideoEncoderWrapper::InitEncode(const VideoCodec* codec_settings, int32_t number_of_cores, size_t max_payload_size) { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(jni); number_of_cores_ = number_of_cores; codec_settings_ = *codec_settings; @@ -72,16 +71,17 @@ int32_t VideoEncoderWrapper::InitEncodeInternal(JNIEnv* jni) { automatic_resize_on = true; } - jobject settings = Java_Settings_Constructor( + ScopedJavaLocalRef settings = Java_Settings_Constructor( jni, number_of_cores_, codec_settings_.width, codec_settings_.height, codec_settings_.startBitrate, codec_settings_.maxFramerate, automatic_resize_on); - jobject callback = Java_VideoEncoderWrapper_createEncoderCallback( - jni, jlongFromPointer(this)); + ScopedJavaLocalRef callback = + Java_VideoEncoderWrapper_createEncoderCallback(jni, + jlongFromPointer(this)); - jobject ret = - Java_VideoEncoder_initEncode(jni, *encoder_, settings, callback); + ScopedJavaLocalRef ret = + Java_VideoEncoder_initEncode(jni, encoder_, settings, callback); if (JavaToNativeVideoCodecStatus(jni, ret) == WEBRTC_VIDEO_CODEC_OK) { initialized_ = true; @@ -98,8 +98,7 @@ int32_t VideoEncoderWrapper::RegisterEncodeCompleteCallback( int32_t VideoEncoderWrapper::Release() { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(jni); - jobject ret = Java_VideoEncoder_release(jni, *encoder_); + ScopedJavaLocalRef ret = Java_VideoEncoder_release(jni, encoder_); frame_extra_infos_.clear(); initialized_ = false; encoder_queue_ = nullptr; @@ -116,28 +115,28 @@ int32_t VideoEncoderWrapper::Encode( } JNIEnv* jni = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(jni); // Construct encode info. - jobjectArray j_frame_types = NativeToJavaFrameTypeArray(jni, *frame_types); - jobject encode_info = Java_EncodeInfo_Constructor(jni, j_frame_types); + ScopedJavaLocalRef j_frame_types = + NativeToJavaFrameTypeArray(jni, *frame_types); + ScopedJavaLocalRef encode_info = + Java_EncodeInfo_Constructor(jni, j_frame_types); FrameExtraInfo info; info.capture_time_ns = frame.timestamp_us() * rtc::kNumNanosecsPerMicrosec; info.timestamp_rtp = frame.timestamp(); frame_extra_infos_.push_back(info); - jobject ret = Java_VideoEncoder_encode( - jni, *encoder_, NativeToJavaFrame(jni, frame), encode_info); + ScopedJavaLocalRef ret = Java_VideoEncoder_encode( + jni, encoder_, NativeToJavaFrame(jni, frame), encode_info); return HandleReturnCode(jni, ret); } int32_t VideoEncoderWrapper::SetChannelParameters(uint32_t packet_loss, int64_t rtt) { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(jni); - jobject ret = Java_VideoEncoder_setChannelParameters( - jni, *encoder_, (jshort)packet_loss, (jlong)rtt); + ScopedJavaLocalRef ret = Java_VideoEncoder_setChannelParameters( + jni, encoder_, (jshort)packet_loss, (jlong)rtt); return HandleReturnCode(jni, ret); } @@ -145,20 +144,19 @@ int32_t VideoEncoderWrapper::SetRateAllocation( const BitrateAllocation& allocation, uint32_t framerate) { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(jni); - jobject j_bitrate_allocation = ToJavaBitrateAllocation(jni, allocation); - jobject ret = Java_VideoEncoder_setRateAllocation( - jni, *encoder_, j_bitrate_allocation, (jint)framerate); + ScopedJavaLocalRef j_bitrate_allocation = + ToJavaBitrateAllocation(jni, allocation); + ScopedJavaLocalRef ret = Java_VideoEncoder_setRateAllocation( + jni, encoder_, j_bitrate_allocation, (jint)framerate); return HandleReturnCode(jni, ret); } VideoEncoderWrapper::ScalingSettings VideoEncoderWrapper::GetScalingSettings() const { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(jni); - jobject j_scaling_settings = - Java_VideoEncoder_getScalingSettings(jni, *encoder_); + ScopedJavaLocalRef j_scaling_settings = + Java_VideoEncoder_getScalingSettings(jni, encoder_); bool isOn = Java_VideoEncoderWrapper_getScalingSettingsOn(jni, j_scaling_settings); @@ -178,18 +176,18 @@ const char* VideoEncoderWrapper::ImplementationName() const { } void VideoEncoderWrapper::OnEncodedFrame(JNIEnv* jni, - jobject j_caller, - jobject j_buffer, + const JavaRef& j_caller, + const JavaRef& j_buffer, jint encoded_width, jint encoded_height, jlong capture_time_ns, jint frame_type, jint rotation, jboolean complete_frame, - jobject j_qp) { + const JavaRef& j_qp) { const uint8_t* buffer = - static_cast(jni->GetDirectBufferAddress(j_buffer)); - const size_t buffer_size = jni->GetDirectBufferCapacity(j_buffer); + static_cast(jni->GetDirectBufferAddress(j_buffer.obj())); + const size_t buffer_size = jni->GetDirectBufferCapacity(j_buffer.obj()); std::vector buffer_copy(buffer_size); memcpy(buffer_copy.data(), buffer, buffer_size); @@ -236,7 +234,8 @@ void VideoEncoderWrapper::OnEncodedFrame(JNIEnv* jni, }); } -int32_t VideoEncoderWrapper::HandleReturnCode(JNIEnv* jni, jobject code) { +int32_t VideoEncoderWrapper::HandleReturnCode(JNIEnv* jni, + const JavaRef& code) { int32_t value = JavaToNativeVideoCodecStatus(jni, code); if (value < 0) { // Any errors are represented by negative values. // Try resetting the codec. @@ -358,31 +357,33 @@ CodecSpecificInfo VideoEncoderWrapper::ParseCodecSpecificInfo( return info; } -jobject VideoEncoderWrapper::ToJavaBitrateAllocation( +ScopedJavaLocalRef VideoEncoderWrapper::ToJavaBitrateAllocation( JNIEnv* jni, const BitrateAllocation& allocation) { - jobjectArray j_allocation_array = jni->NewObjectArray( - kMaxSpatialLayers, *int_array_class_, nullptr /* initial */); + ScopedJavaLocalRef j_allocation_array( + jni, jni->NewObjectArray(kMaxSpatialLayers, int_array_class_.obj(), + nullptr /* initial */)); for (int spatial_i = 0; spatial_i < kMaxSpatialLayers; ++spatial_i) { - jintArray j_array_spatial_layer = jni->NewIntArray(kMaxTemporalStreams); - jint* array_spatial_layer = - jni->GetIntArrayElements(j_array_spatial_layer, nullptr /* isCopy */); + ScopedJavaLocalRef j_array_spatial_layer( + jni, jni->NewIntArray(kMaxTemporalStreams)); + jint* array_spatial_layer = jni->GetIntArrayElements( + j_array_spatial_layer.obj(), nullptr /* isCopy */); for (int temporal_i = 0; temporal_i < kMaxTemporalStreams; ++temporal_i) { array_spatial_layer[temporal_i] = allocation.GetBitrate(spatial_i, temporal_i); } - jni->ReleaseIntArrayElements(j_array_spatial_layer, array_spatial_layer, - JNI_COMMIT); + jni->ReleaseIntArrayElements(j_array_spatial_layer.obj(), + array_spatial_layer, JNI_COMMIT); - jni->SetObjectArrayElement(j_allocation_array, spatial_i, - j_array_spatial_layer); + jni->SetObjectArrayElement(j_allocation_array.obj(), spatial_i, + j_array_spatial_layer.obj()); } return Java_BitrateAllocation_Constructor(jni, j_allocation_array); } std::string VideoEncoderWrapper::GetImplementationName(JNIEnv* jni) const { - jstring jname = Java_VideoEncoder_getImplementationName(jni, *encoder_); - return JavaToStdString(jni, jname); + return JavaToStdString( + jni, Java_VideoEncoder_getImplementationName(jni, encoder_)); } } // namespace jni diff --git a/sdk/android/src/jni/videoencoderwrapper.h b/sdk/android/src/jni/videoencoderwrapper.h index d4089a7458..385db511c3 100644 --- a/sdk/android/src/jni/videoencoderwrapper.h +++ b/sdk/android/src/jni/videoencoderwrapper.h @@ -29,7 +29,7 @@ namespace jni { // Wraps a Java encoder and delegates all calls to it. class VideoEncoderWrapper : public VideoEncoder { public: - VideoEncoderWrapper(JNIEnv* jni, jobject j_encoder); + VideoEncoderWrapper(JNIEnv* jni, const JavaRef& j_encoder); int32_t InitEncode(const VideoCodec* codec_settings, int32_t number_of_cores, @@ -55,15 +55,15 @@ class VideoEncoderWrapper : public VideoEncoder { // Should only be called by JNI. void OnEncodedFrame(JNIEnv* jni, - jobject j_caller, - jobject j_buffer, + const JavaRef& j_caller, + const JavaRef& j_buffer, jint encoded_width, jint encoded_height, jlong capture_time_ms, jint frame_type, jint rotation, jboolean complete_frame, - jobject j_qp); + const JavaRef& j_qp); const char* ImplementationName() const override; @@ -78,18 +78,19 @@ class VideoEncoderWrapper : public VideoEncoder { // Takes Java VideoCodecStatus, handles it and returns WEBRTC_VIDEO_CODEC_* // status code. - int32_t HandleReturnCode(JNIEnv* jni, jobject code); + int32_t HandleReturnCode(JNIEnv* jni, const JavaRef& code); RTPFragmentationHeader ParseFragmentationHeader( const std::vector& buffer); int ParseQp(const std::vector& buffer); CodecSpecificInfo ParseCodecSpecificInfo(const EncodedImage& frame); - jobject ToJavaBitrateAllocation(JNIEnv* jni, - const BitrateAllocation& allocation); + ScopedJavaLocalRef ToJavaBitrateAllocation( + JNIEnv* jni, + const BitrateAllocation& allocation); std::string GetImplementationName(JNIEnv* jni) const; - const ScopedGlobalRef encoder_; - const ScopedGlobalRef int_array_class_; + const ScopedJavaGlobalRef encoder_; + const ScopedJavaGlobalRef int_array_class_; std::string implementation_name_; diff --git a/sdk/android/src/jni/videofilerenderer.cc b/sdk/android/src/jni/videofilerenderer.cc index f03b430f83..0cee4fd8cf 100644 --- a/sdk/android/src/jni/videofilerenderer.cc +++ b/sdk/android/src/jni/videofilerenderer.cc @@ -12,42 +12,44 @@ #include "rtc_base/checks.h" #include "rtc_base/logging.h" +#include "sdk/android/generated_video_jni/jni/VideoFileRenderer_jni.h" +#include "sdk/android/src/jni/scoped_java_ref.h" #include "third_party/libyuv/include/libyuv/scale.h" namespace webrtc { namespace jni { -extern "C" JNIEXPORT void JNICALL -Java_org_webrtc_VideoFileRenderer_nativeI420Scale(JNIEnv* jni, - jclass, - jobject j_src_buffer_y, - jint j_src_stride_y, - jobject j_src_buffer_u, - jint j_src_stride_u, - jobject j_src_buffer_v, - jint j_src_stride_v, - jint width, - jint height, - jbyteArray j_dst_buffer, - jint dstWidth, - jint dstHeight) { - size_t src_size_y = jni->GetDirectBufferCapacity(j_src_buffer_y); - size_t src_size_u = jni->GetDirectBufferCapacity(j_src_buffer_u); - size_t src_size_v = jni->GetDirectBufferCapacity(j_src_buffer_v); - size_t dst_size = jni->GetDirectBufferCapacity(j_dst_buffer); +static void JNI_VideoFileRenderer_I420Scale( + JNIEnv* jni, + const JavaParamRef&, + const JavaParamRef& j_src_buffer_y, + jint j_src_stride_y, + const JavaParamRef& j_src_buffer_u, + jint j_src_stride_u, + const JavaParamRef& j_src_buffer_v, + jint j_src_stride_v, + jint width, + jint height, + const JavaParamRef& j_dst_buffer, + jint dstWidth, + jint dstHeight) { + size_t src_size_y = jni->GetDirectBufferCapacity(j_src_buffer_y.obj()); + size_t src_size_u = jni->GetDirectBufferCapacity(j_src_buffer_u.obj()); + size_t src_size_v = jni->GetDirectBufferCapacity(j_src_buffer_v.obj()); + size_t dst_size = jni->GetDirectBufferCapacity(j_dst_buffer.obj()); int dst_stride = dstWidth; RTC_CHECK_GE(src_size_y, j_src_stride_y * height); RTC_CHECK_GE(src_size_u, j_src_stride_u * height / 4); RTC_CHECK_GE(src_size_v, j_src_stride_v * height / 4); RTC_CHECK_GE(dst_size, dst_stride * dstHeight * 3 / 2); - uint8_t* src_y = - reinterpret_cast(jni->GetDirectBufferAddress(j_src_buffer_y)); - uint8_t* src_u = - reinterpret_cast(jni->GetDirectBufferAddress(j_src_buffer_u)); - uint8_t* src_v = - reinterpret_cast(jni->GetDirectBufferAddress(j_src_buffer_v)); - uint8_t* dst = - reinterpret_cast(jni->GetDirectBufferAddress(j_dst_buffer)); + uint8_t* src_y = reinterpret_cast( + jni->GetDirectBufferAddress(j_src_buffer_y.obj())); + uint8_t* src_u = reinterpret_cast( + jni->GetDirectBufferAddress(j_src_buffer_u.obj())); + uint8_t* src_v = reinterpret_cast( + jni->GetDirectBufferAddress(j_src_buffer_v.obj())); + uint8_t* dst = reinterpret_cast( + jni->GetDirectBufferAddress(j_dst_buffer.obj())); uint8_t* dst_y = dst; size_t dst_stride_y = dst_stride; diff --git a/sdk/android/src/jni/videoframe.cc b/sdk/android/src/jni/videoframe.cc index 2b177c764a..6341b822cb 100644 --- a/sdk/android/src/jni/videoframe.cc +++ b/sdk/android/src/jni/videoframe.cc @@ -36,8 +36,11 @@ class AndroidVideoI420Buffer : public I420BufferInterface { // Adopts and takes ownership of the Java VideoFrame.Buffer. I.e. retain() // will not be called, but release() will be called when the returned // AndroidVideoBuffer is destroyed. - static rtc::scoped_refptr - Adopt(JNIEnv* jni, int width, int height, jobject j_video_frame_buffer); + static rtc::scoped_refptr Adopt( + JNIEnv* jni, + int width, + int height, + const JavaRef& j_video_frame_buffer); protected: // Should not be called directly. Adopts the buffer. Use Adopt() instead for @@ -45,7 +48,7 @@ class AndroidVideoI420Buffer : public I420BufferInterface { AndroidVideoI420Buffer(JNIEnv* jni, int width, int height, - jobject j_video_frame_buffer); + const JavaRef& j_video_frame_buffer); ~AndroidVideoI420Buffer(); private: @@ -63,7 +66,7 @@ class AndroidVideoI420Buffer : public I420BufferInterface { const int width_; const int height_; // Holds a VideoFrame.I420Buffer. - const ScopedGlobalRef j_video_frame_buffer_; + const ScopedJavaGlobalRef j_video_frame_buffer_; const uint8_t* data_y_; const uint8_t* data_u_; @@ -77,25 +80,32 @@ rtc::scoped_refptr AndroidVideoI420Buffer::Adopt( JNIEnv* jni, int width, int height, - jobject j_video_frame_buffer) { + const JavaRef& j_video_frame_buffer) { return new rtc::RefCountedObject( jni, width, height, j_video_frame_buffer); } -AndroidVideoI420Buffer::AndroidVideoI420Buffer(JNIEnv* jni, - int width, - int height, - jobject j_video_frame_buffer) +AndroidVideoI420Buffer::AndroidVideoI420Buffer( + JNIEnv* jni, + int width, + int height, + const JavaRef& j_video_frame_buffer) : width_(width), height_(height), j_video_frame_buffer_(jni, j_video_frame_buffer) { - jobject j_data_y = Java_I420Buffer_getDataY(jni, j_video_frame_buffer); - jobject j_data_u = Java_I420Buffer_getDataU(jni, j_video_frame_buffer); - jobject j_data_v = Java_I420Buffer_getDataV(jni, j_video_frame_buffer); + ScopedJavaLocalRef j_data_y = + Java_I420Buffer_getDataY(jni, j_video_frame_buffer); + ScopedJavaLocalRef j_data_u = + Java_I420Buffer_getDataU(jni, j_video_frame_buffer); + ScopedJavaLocalRef j_data_v = + Java_I420Buffer_getDataV(jni, j_video_frame_buffer); - data_y_ = static_cast(jni->GetDirectBufferAddress(j_data_y)); - data_u_ = static_cast(jni->GetDirectBufferAddress(j_data_u)); - data_v_ = static_cast(jni->GetDirectBufferAddress(j_data_v)); + data_y_ = + static_cast(jni->GetDirectBufferAddress(j_data_y.obj())); + data_u_ = + static_cast(jni->GetDirectBufferAddress(j_data_u.obj())); + data_v_ = + static_cast(jni->GetDirectBufferAddress(j_data_v.obj())); stride_y_ = Java_I420Buffer_getStrideY(jni, j_video_frame_buffer); stride_u_ = Java_I420Buffer_getStrideU(jni, j_video_frame_buffer); @@ -104,27 +114,28 @@ AndroidVideoI420Buffer::AndroidVideoI420Buffer(JNIEnv* jni, AndroidVideoI420Buffer::~AndroidVideoI420Buffer() { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - Java_Buffer_release(jni, *j_video_frame_buffer_); + Java_Buffer_release(jni, j_video_frame_buffer_); } } // namespace -int64_t GetJavaVideoFrameTimestampNs(JNIEnv* jni, jobject j_video_frame) { +int64_t GetJavaVideoFrameTimestampNs(JNIEnv* jni, + const JavaRef& j_video_frame) { return Java_VideoFrame_getTimestampNs(jni, j_video_frame); } -Matrix::Matrix(JNIEnv* jni, jfloatArray a) { - RTC_CHECK_EQ(16, jni->GetArrayLength(a)); - jfloat* ptr = jni->GetFloatArrayElements(a, nullptr); +Matrix::Matrix(JNIEnv* jni, const JavaRef& a) { + RTC_CHECK_EQ(16, jni->GetArrayLength(a.obj())); + jfloat* ptr = jni->GetFloatArrayElements(a.obj(), nullptr); for (int i = 0; i < 16; ++i) { elem_[i] = ptr[i]; } - jni->ReleaseFloatArrayElements(a, ptr, 0); + jni->ReleaseFloatArrayElements(a.obj(), ptr, 0); } -jfloatArray Matrix::ToJava(JNIEnv* jni) const { - jfloatArray matrix = jni->NewFloatArray(16); - jni->SetFloatArrayRegion(matrix, 0, 16, elem_); +ScopedJavaLocalRef Matrix::ToJava(JNIEnv* jni) const { + ScopedJavaLocalRef matrix(jni, jni->NewFloatArray(16)); + jni->SetFloatArrayRegion(matrix.obj(), 0, 16, elem_); return matrix; } @@ -200,9 +211,10 @@ static const int kBufferAlignment = 64; NativeHandleImpl::NativeHandleImpl(int id, const Matrix& matrix) : oes_texture_id(id), sampling_matrix(matrix) {} -NativeHandleImpl::NativeHandleImpl(JNIEnv* jni, - jint j_oes_texture_id, - jfloatArray j_transform_matrix) +NativeHandleImpl::NativeHandleImpl( + JNIEnv* jni, + jint j_oes_texture_id, + const JavaRef& j_transform_matrix) : oes_texture_id(j_oes_texture_id), sampling_matrix(jni, j_transform_matrix) {} @@ -262,11 +274,11 @@ rtc::scoped_refptr AndroidTextureBuffer::ToI420() { rtc::Bind(&AlignedFree, yuv_data.release())); JNIEnv* jni = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(jni); // TODO(sakal): This call to a deperecated method will be removed when // AndroidTextureBuffer is removed. - jobject byte_buffer = jni->NewDirectByteBuffer(y_data, size); + ScopedJavaLocalRef byte_buffer = + NewDirectByteBuffer(jni, y_data, size); SurfaceTextureHelperTextureToYUV( jni, surface_texture_helper_->GetJavaSurfaceTextureHelper(), byte_buffer, width(), height(), stride, native_handle_); @@ -275,31 +287,33 @@ rtc::scoped_refptr AndroidTextureBuffer::ToI420() { rtc::scoped_refptr AndroidVideoBuffer::Adopt( JNIEnv* jni, - jobject j_video_frame_buffer) { + const JavaRef& j_video_frame_buffer) { return new rtc::RefCountedObject(jni, j_video_frame_buffer); } rtc::scoped_refptr AndroidVideoBuffer::Create( JNIEnv* jni, - jobject j_video_frame_buffer) { + const JavaRef& j_video_frame_buffer) { Java_Buffer_retain(jni, j_video_frame_buffer); return Adopt(jni, j_video_frame_buffer); } -AndroidVideoBuffer::AndroidVideoBuffer(JNIEnv* jni, - jobject j_video_frame_buffer) +AndroidVideoBuffer::AndroidVideoBuffer( + JNIEnv* jni, + const JavaRef& j_video_frame_buffer) : width_(Java_Buffer_getWidth(jni, j_video_frame_buffer)), height_(Java_Buffer_getHeight(jni, j_video_frame_buffer)), j_video_frame_buffer_(jni, j_video_frame_buffer) {} AndroidVideoBuffer::~AndroidVideoBuffer() { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - Java_Buffer_release(jni, *j_video_frame_buffer_); + Java_Buffer_release(jni, j_video_frame_buffer_); } -jobject AndroidVideoBuffer::video_frame_buffer() const { - return *j_video_frame_buffer_; +const ScopedJavaGlobalRef& AndroidVideoBuffer::video_frame_buffer() + const { + return j_video_frame_buffer_; } rtc::scoped_refptr AndroidVideoBuffer::CropAndScale( @@ -310,9 +324,9 @@ rtc::scoped_refptr AndroidVideoBuffer::CropAndScale( int crop_height, int scale_width, int scale_height) { - return Adopt(jni, Java_Buffer_cropAndScale( - jni, *j_video_frame_buffer_, crop_x, crop_y, crop_width, - crop_height, scale_width, scale_height)); + return Adopt(jni, Java_Buffer_cropAndScale(jni, j_video_frame_buffer_, crop_x, + crop_y, crop_width, crop_height, + scale_width, scale_height)); } VideoFrameBuffer::Type AndroidVideoBuffer::type() const { @@ -329,8 +343,8 @@ int AndroidVideoBuffer::height() const { rtc::scoped_refptr AndroidVideoBuffer::ToI420() { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(jni); - jobject j_i420_buffer = Java_Buffer_toI420(jni, *j_video_frame_buffer_); + ScopedJavaLocalRef j_i420_buffer = + Java_Buffer_toI420(jni, j_video_frame_buffer_); // We don't need to retain the buffer because toI420 returns a new object that // we are assumed to take the ownership of. @@ -338,9 +352,10 @@ rtc::scoped_refptr AndroidVideoBuffer::ToI420() { } VideoFrame JavaToNativeFrame(JNIEnv* jni, - jobject j_video_frame, + const JavaRef& j_video_frame, uint32_t timestamp_rtp) { - jobject j_video_frame_buffer = Java_VideoFrame_getBuffer(jni, j_video_frame); + ScopedJavaLocalRef j_video_frame_buffer = + Java_VideoFrame_getBuffer(jni, j_video_frame); int rotation = Java_VideoFrame_getRotation(jni, j_video_frame); int64_t timestamp_ns = Java_VideoFrame_getTimestampNs(jni, j_video_frame); rtc::scoped_refptr buffer = @@ -360,7 +375,8 @@ static bool IsJavaVideoBuffer(rtc::scoped_refptr buffer) { AndroidVideoFrameBuffer::AndroidType::kJavaBuffer; } -jobject NativeToJavaFrame(JNIEnv* jni, const VideoFrame& frame) { +ScopedJavaLocalRef NativeToJavaFrame(JNIEnv* jni, + const VideoFrame& frame) { rtc::scoped_refptr buffer = frame.video_frame_buffer(); if (IsJavaVideoBuffer(buffer)) { @@ -386,36 +402,39 @@ jobject NativeToJavaFrame(JNIEnv* jni, const VideoFrame& frame) { } } -extern "C" JNIEXPORT void JNICALL -Java_org_webrtc_VideoFrame_cropAndScaleI420Native(JNIEnv* jni, - jclass, - jobject j_src_y, - jint src_stride_y, - jobject j_src_u, - jint src_stride_u, - jobject j_src_v, - jint src_stride_v, - jint crop_x, - jint crop_y, - jint crop_width, - jint crop_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, - jint scale_width, - jint scale_height) { +static void JNI_VideoFrame_CropAndScaleI420( + JNIEnv* jni, + const JavaParamRef&, + const JavaParamRef& j_src_y, + jint src_stride_y, + const JavaParamRef& j_src_u, + jint src_stride_u, + const JavaParamRef& j_src_v, + jint src_stride_v, + jint crop_x, + jint crop_y, + jint crop_width, + jint crop_height, + const JavaParamRef& j_dst_y, + jint dst_stride_y, + const JavaParamRef& j_dst_u, + jint dst_stride_u, + const JavaParamRef& j_dst_v, + jint dst_stride_v, + jint scale_width, + jint scale_height) { uint8_t const* src_y = - static_cast(jni->GetDirectBufferAddress(j_src_y)); + static_cast(jni->GetDirectBufferAddress(j_src_y.obj())); uint8_t const* src_u = - static_cast(jni->GetDirectBufferAddress(j_src_u)); + static_cast(jni->GetDirectBufferAddress(j_src_u.obj())); uint8_t const* src_v = - static_cast(jni->GetDirectBufferAddress(j_src_v)); - uint8_t* dst_y = static_cast(jni->GetDirectBufferAddress(j_dst_y)); - uint8_t* dst_u = static_cast(jni->GetDirectBufferAddress(j_dst_u)); - uint8_t* dst_v = static_cast(jni->GetDirectBufferAddress(j_dst_v)); + static_cast(jni->GetDirectBufferAddress(j_src_v.obj())); + uint8_t* dst_y = + static_cast(jni->GetDirectBufferAddress(j_dst_y.obj())); + uint8_t* dst_u = + static_cast(jni->GetDirectBufferAddress(j_dst_u.obj())); + uint8_t* dst_v = + static_cast(jni->GetDirectBufferAddress(j_dst_v.obj())); // Perform cropping using pointer arithmetic. src_y += crop_x + crop_y * src_stride_y; diff --git a/sdk/android/src/jni/videoframe.h b/sdk/android/src/jni/videoframe.h index 9dac238e38..66abced074 100644 --- a/sdk/android/src/jni/videoframe.h +++ b/sdk/android/src/jni/videoframe.h @@ -18,6 +18,7 @@ #include "api/video/video_rotation.h" #include "rtc_base/callback.h" #include "sdk/android/src/jni/jni_helpers.h" +#include "sdk/android/src/jni/surfacetexturehelper.h" namespace webrtc { namespace jni { @@ -28,11 +29,12 @@ class SurfaceTextureHelper; // in-place. class Matrix { public: - Matrix(JNIEnv* jni, jfloatArray a); + Matrix(JNIEnv* jni, const JavaRef& a); - static Matrix fromAndroidGraphicsMatrix(JNIEnv* jni, jobject j_matrix); + static Matrix fromAndroidGraphicsMatrix(JNIEnv* jni, + const JavaRef& j_matrix); - jfloatArray ToJava(JNIEnv* jni) const; + ScopedJavaLocalRef ToJava(JNIEnv* jni) const; // Crop arguments are relative to original size. void Crop(float cropped_width, @@ -53,7 +55,7 @@ class Matrix { struct NativeHandleImpl { NativeHandleImpl(JNIEnv* jni, jint j_oes_texture_id, - jfloatArray j_transform_matrix); + const JavaRef& j_transform_matrix); NativeHandleImpl(int id, const Matrix& matrix); @@ -103,18 +105,18 @@ class AndroidVideoBuffer : public AndroidVideoFrameBuffer { // Creates a native VideoFrameBuffer from a Java VideoFrame.Buffer. static rtc::scoped_refptr Create( JNIEnv* jni, - jobject j_video_frame_buffer); + const JavaRef& j_video_frame_buffer); // Similar to the Create() above, but adopts and takes ownership of the Java // VideoFrame.Buffer. I.e. retain() will not be called, but release() will be // called when the returned AndroidVideoBuffer is destroyed. static rtc::scoped_refptr Adopt( JNIEnv* jni, - jobject j_video_frame_buffer); + const JavaRef& j_video_frame_buffer); ~AndroidVideoBuffer() override; - jobject video_frame_buffer() const; + const ScopedJavaGlobalRef& video_frame_buffer() const; // Crops a region defined by |crop_x|, |crop_y|, |crop_width| and // |crop_height|. Scales it to size |scale_width| x |scale_height|. @@ -129,7 +131,7 @@ class AndroidVideoBuffer : public AndroidVideoFrameBuffer { protected: // Should not be called directly. Adopts the Java VideoFrame.Buffer. Use // Create() or Adopt() instead for clarity. - AndroidVideoBuffer(JNIEnv* jni, jobject j_video_frame_buffer); + AndroidVideoBuffer(JNIEnv* jni, const JavaRef& j_video_frame_buffer); private: Type type() const override; @@ -143,16 +145,18 @@ class AndroidVideoBuffer : public AndroidVideoFrameBuffer { const int width_; const int height_; // Holds a VideoFrame.Buffer. - const ScopedGlobalRef j_video_frame_buffer_; + const ScopedJavaGlobalRef j_video_frame_buffer_; }; VideoFrame JavaToNativeFrame(JNIEnv* jni, - jobject j_video_frame, + const JavaRef& j_video_frame, uint32_t timestamp_rtp); -jobject NativeToJavaFrame(JNIEnv* jni, const VideoFrame& frame); +ScopedJavaLocalRef NativeToJavaFrame(JNIEnv* jni, + const VideoFrame& frame); -int64_t GetJavaVideoFrameTimestampNs(JNIEnv* jni, jobject j_video_frame); +int64_t GetJavaVideoFrameTimestampNs(JNIEnv* jni, + const JavaRef& j_video_frame); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/videotrack.cc b/sdk/android/src/jni/videotrack.cc index e49b20c3e5..b9db009b74 100644 --- a/sdk/android/src/jni/videotrack.cc +++ b/sdk/android/src/jni/videotrack.cc @@ -13,6 +13,7 @@ #include "api/mediastreaminterface.h" #include "rtc_base/logging.h" #include "sdk/android/generated_video_jni/jni/VideoSink_jni.h" +#include "sdk/android/generated_video_jni/jni/VideoTrack_jni.h" #include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/videoframe.h" @@ -23,56 +24,53 @@ namespace { class VideoSinkWrapper : public rtc::VideoSinkInterface { public: - VideoSinkWrapper(JNIEnv* jni, jobject j_sink); + VideoSinkWrapper(JNIEnv* jni, const JavaRef& j_sink); ~VideoSinkWrapper() override {} private: void OnFrame(const VideoFrame& frame) override; - const ScopedGlobalRef j_sink_; + const ScopedJavaGlobalRef j_sink_; }; -VideoSinkWrapper::VideoSinkWrapper(JNIEnv* jni, jobject j_sink) +VideoSinkWrapper::VideoSinkWrapper(JNIEnv* jni, const JavaRef& j_sink) : j_sink_(jni, j_sink) {} void VideoSinkWrapper::OnFrame(const VideoFrame& frame) { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - ScopedLocalRefFrame local_ref_frame(jni); - Java_VideoSink_onFrame(jni, *j_sink_, NativeToJavaFrame(jni, frame)); + Java_VideoSink_onFrame(jni, j_sink_, NativeToJavaFrame(jni, frame)); } } // namespace -extern "C" JNIEXPORT void JNICALL -Java_org_webrtc_VideoTrack_nativeAddSink(JNIEnv* jni, - jclass, - jlong j_native_track, - jlong j_native_sink) { +static void JNI_VideoTrack_AddSink(JNIEnv* jni, + const JavaParamRef&, + jlong j_native_track, + jlong j_native_sink) { reinterpret_cast(j_native_track) ->AddOrUpdateSink( reinterpret_cast*>(j_native_sink), rtc::VideoSinkWants()); } -extern "C" JNIEXPORT void JNICALL -Java_org_webrtc_VideoTrack_nativeRemoveSink(JNIEnv* jni, - jclass, - jlong j_native_track, - jlong j_native_sink) { +static void JNI_VideoTrack_RemoveSink(JNIEnv* jni, + const JavaParamRef&, + jlong j_native_track, + jlong j_native_sink) { reinterpret_cast(j_native_track) ->RemoveSink(reinterpret_cast*>( j_native_sink)); } -extern "C" JNIEXPORT jlong JNICALL -Java_org_webrtc_VideoTrack_nativeWrapSink(JNIEnv* jni, jclass, jobject sink) { +static jlong JNI_VideoTrack_WrapSink(JNIEnv* jni, + const JavaParamRef&, + const JavaParamRef& sink) { return jlongFromPointer(new VideoSinkWrapper(jni, sink)); } -extern "C" JNIEXPORT void JNICALL -Java_org_webrtc_VideoTrack_nativeFreeSink(JNIEnv* jni, - jclass, - jlong j_native_sink) { +static void JNI_VideoTrack_FreeSink(JNIEnv* jni, + const JavaParamRef&, + jlong j_native_sink) { delete reinterpret_cast*>(j_native_sink); } diff --git a/sdk/android/src/jni/vp8codec.cc b/sdk/android/src/jni/vp8codec.cc index 000652ce80..3011222972 100644 --- a/sdk/android/src/jni/vp8codec.cc +++ b/sdk/android/src/jni/vp8codec.cc @@ -11,22 +11,20 @@ #include #include "modules/video_coding/codecs/vp8/include/vp8.h" +#include "sdk/android/generated_video_jni/jni/VP8Decoder_jni.h" +#include "sdk/android/generated_video_jni/jni/VP8Encoder_jni.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { namespace jni { -JNI_FUNCTION_DECLARATION(jlong, - VP8Encoder_createNativeEncoder, - JNIEnv* jni, - jobject) { +static jlong JNI_VP8Encoder_CreateEncoder(JNIEnv* jni, + const JavaParamRef&) { return jlongFromPointer(VP8Encoder::Create().release()); } -JNI_FUNCTION_DECLARATION(jlong, - VP8Decoder_createNativeDecoder, - JNIEnv* jni, - jobject) { +static jlong JNI_VP8Decoder_CreateDecoder(JNIEnv* jni, + const JavaParamRef&) { return jlongFromPointer(VP8Decoder::Create().release()); } diff --git a/sdk/android/src/jni/vp9codec.cc b/sdk/android/src/jni/vp9codec.cc index 8ec51ae336..e49d276fef 100644 --- a/sdk/android/src/jni/vp9codec.cc +++ b/sdk/android/src/jni/vp9codec.cc @@ -11,36 +11,30 @@ #include #include "modules/video_coding/codecs/vp9/include/vp9.h" +#include "sdk/android/generated_video_jni/jni/VP9Decoder_jni.h" +#include "sdk/android/generated_video_jni/jni/VP9Encoder_jni.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { namespace jni { -JNI_FUNCTION_DECLARATION(jlong, - VP9Encoder_createNativeEncoder, - JNIEnv* jni, - jobject) { +static jlong JNI_VP9Encoder_CreateEncoder(JNIEnv* jni, + const JavaParamRef& w) { return jlongFromPointer(VP9Encoder::Create().release()); } -JNI_FUNCTION_DECLARATION(jboolean, - VP9Encoder_isSupported, - JNIEnv* jni, - jclass) { +static jboolean JNI_VP9Encoder_IsSupported(JNIEnv* jni, + const JavaParamRef&) { return VP9Encoder::IsSupported(); } -JNI_FUNCTION_DECLARATION(jlong, - VP9Decoder_createNativeDecoder, - JNIEnv* jni, - jobject) { +static jlong JNI_VP9Decoder_CreateDecoder(JNIEnv* jni, + const JavaParamRef& w) { return jlongFromPointer(VP9Decoder::Create().release()); } -JNI_FUNCTION_DECLARATION(jboolean, - VP9Decoder_isSupported, - JNIEnv* jni, - jclass) { +static jboolean JNI_VP9Decoder_IsSupported(JNIEnv* jni, + const JavaParamRef&) { return VP9Decoder::IsSupported(); } diff --git a/sdk/android/src/jni/wrapped_native_i420_buffer.cc b/sdk/android/src/jni/wrapped_native_i420_buffer.cc index 4e31b99e19..eab2840553 100644 --- a/sdk/android/src/jni/wrapped_native_i420_buffer.cc +++ b/sdk/android/src/jni/wrapped_native_i420_buffer.cc @@ -17,26 +17,23 @@ namespace webrtc { namespace jni { // TODO(magjed): Write a test for this function. -jobject WrapI420Buffer( +ScopedJavaLocalRef WrapI420Buffer( JNIEnv* jni, const rtc::scoped_refptr& i420_buffer) { - jobject y_buffer = - jni->NewDirectByteBuffer(const_cast(i420_buffer->DataY()), - i420_buffer->StrideY() * i420_buffer->height()); - jobject u_buffer = jni->NewDirectByteBuffer( - const_cast(i420_buffer->DataU()), - i420_buffer->StrideU() * i420_buffer->ChromaHeight()); - jobject v_buffer = jni->NewDirectByteBuffer( - const_cast(i420_buffer->DataV()), - i420_buffer->StrideV() * i420_buffer->ChromaHeight()); + ScopedJavaLocalRef y_buffer = + NewDirectByteBuffer(jni, const_cast(i420_buffer->DataY()), + i420_buffer->StrideY() * i420_buffer->height()); + ScopedJavaLocalRef u_buffer = + NewDirectByteBuffer(jni, const_cast(i420_buffer->DataU()), + i420_buffer->StrideU() * i420_buffer->ChromaHeight()); + ScopedJavaLocalRef v_buffer = + NewDirectByteBuffer(jni, const_cast(i420_buffer->DataV()), + i420_buffer->StrideV() * i420_buffer->ChromaHeight()); - jobject j_wrapped_native_i420_buffer = - Java_WrappedNativeI420Buffer_Constructor( - jni, i420_buffer->width(), i420_buffer->height(), y_buffer, - i420_buffer->StrideY(), u_buffer, i420_buffer->StrideU(), v_buffer, - i420_buffer->StrideV(), jlongFromPointer(i420_buffer.get())); - - return j_wrapped_native_i420_buffer; + return Java_WrappedNativeI420Buffer_Constructor( + jni, i420_buffer->width(), i420_buffer->height(), y_buffer, + i420_buffer->StrideY(), u_buffer, i420_buffer->StrideU(), v_buffer, + i420_buffer->StrideV(), jlongFromPointer(i420_buffer.get())); } } // namespace jni diff --git a/sdk/android/src/jni/wrapped_native_i420_buffer.h b/sdk/android/src/jni/wrapped_native_i420_buffer.h index 5de98d81cc..b7e0fdec16 100644 --- a/sdk/android/src/jni/wrapped_native_i420_buffer.h +++ b/sdk/android/src/jni/wrapped_native_i420_buffer.h @@ -14,13 +14,14 @@ #include #include "api/video/video_frame_buffer.h" +#include "sdk/android/src/jni/scoped_java_ref.h" namespace webrtc { namespace jni { // This function wraps the C++ I420 buffer and returns a Java // VideoFrame.I420Buffer as a jobject. -jobject WrapI420Buffer( +ScopedJavaLocalRef WrapI420Buffer( JNIEnv* jni, const rtc::scoped_refptr& i420_buffer); diff --git a/sdk/android/src/jni/wrappednativecodec.cc b/sdk/android/src/jni/wrappednativecodec.cc index 816d522058..36e3db2262 100644 --- a/sdk/android/src/jni/wrappednativecodec.cc +++ b/sdk/android/src/jni/wrappednativecodec.cc @@ -20,8 +20,9 @@ namespace webrtc { namespace jni { -std::unique_ptr JavaToNativeVideoDecoder(JNIEnv* jni, - jobject j_decoder) { +std::unique_ptr JavaToNativeVideoDecoder( + JNIEnv* jni, + const JavaRef& j_decoder) { VideoDecoder* decoder; if (Java_WrappedNativeVideoDecoder_isInstanceOf(jni, j_decoder)) { jlong native_decoder = @@ -34,8 +35,9 @@ std::unique_ptr JavaToNativeVideoDecoder(JNIEnv* jni, return std::unique_ptr(decoder); } -std::unique_ptr JavaToNativeVideoEncoder(JNIEnv* jni, - jobject j_encoder) { +std::unique_ptr JavaToNativeVideoEncoder( + JNIEnv* jni, + const JavaRef& j_encoder) { VideoEncoder* encoder; if (Java_WrappedNativeVideoEncoder_isInstanceOf(jni, j_encoder)) { jlong native_encoder = @@ -48,7 +50,7 @@ std::unique_ptr JavaToNativeVideoEncoder(JNIEnv* jni, return std::unique_ptr(encoder); } -bool IsWrappedSoftwareEncoder(JNIEnv* jni, jobject j_encoder) { +bool IsWrappedSoftwareEncoder(JNIEnv* jni, const JavaRef& j_encoder) { return Java_WrappedNativeVideoEncoder_isWrappedSoftwareEncoder(jni, j_encoder); } diff --git a/sdk/android/src/jni/wrappednativecodec.h b/sdk/android/src/jni/wrappednativecodec.h index 0494296028..62d3aac692 100644 --- a/sdk/android/src/jni/wrappednativecodec.h +++ b/sdk/android/src/jni/wrappednativecodec.h @@ -16,6 +16,7 @@ #include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_encoder.h" +#include "sdk/android/src/jni/scoped_java_ref.h" namespace webrtc { namespace jni { @@ -23,16 +24,18 @@ namespace jni { /* If the j_decoder is a wrapped native decoder, unwrap it. If it is not, * wrap it in a VideoDecoderWrapper. */ -std::unique_ptr JavaToNativeVideoDecoder(JNIEnv* jni, - jobject j_decoder); +std::unique_ptr JavaToNativeVideoDecoder( + JNIEnv* jni, + const JavaRef& j_decoder); /* If the j_encoder is a wrapped native encoder, unwrap it. If it is not, * wrap it in a VideoEncoderWrapper. */ -std::unique_ptr JavaToNativeVideoEncoder(JNIEnv* jni, - jobject j_encoder); +std::unique_ptr JavaToNativeVideoEncoder( + JNIEnv* jni, + const JavaRef& j_encoder); -bool IsWrappedSoftwareEncoder(JNIEnv* jni, jobject j_encoder); +bool IsWrappedSoftwareEncoder(JNIEnv* jni, const JavaRef& j_encoder); } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/yuvhelper.cc b/sdk/android/src/jni/yuvhelper.cc index bdf5375c4f..e2fc351a64 100644 --- a/sdk/android/src/jni/yuvhelper.cc +++ b/sdk/android/src/jni/yuvhelper.cc @@ -10,70 +10,71 @@ #include +#include "sdk/android/generated_video_jni/jni/YuvHelper_jni.h" #include "sdk/android/src/jni/jni_helpers.h" #include "third_party/libyuv/include/libyuv/convert.h" namespace webrtc { namespace jni { -JNI_FUNCTION_DECLARATION(void, - YuvHelper_I420Copy, - JNIEnv* jni, - jclass, - jobject j_src_y, - jint src_stride_y, - jobject j_src_u, - jint src_stride_u, - jobject j_src_v, - jint src_stride_v, - jobject j_dst_y, - jint dst_stride_y, - jobject j_dst_u, - jint dst_stride_u, - jobject j_dst_v, - jint dst_stride_v, - jint width, - jint height) { +void JNI_YuvHelper_I420Copy(JNIEnv* jni, + const JavaParamRef&, + const JavaParamRef& j_src_y, + jint src_stride_y, + const JavaParamRef& j_src_u, + jint src_stride_u, + const JavaParamRef& j_src_v, + jint src_stride_v, + const JavaParamRef& j_dst_y, + jint dst_stride_y, + const JavaParamRef& j_dst_u, + jint dst_stride_u, + const JavaParamRef& j_dst_v, + jint dst_stride_v, + jint width, + jint height) { const uint8_t* src_y = - static_cast(jni->GetDirectBufferAddress(j_src_y)); + static_cast(jni->GetDirectBufferAddress(j_src_y.obj())); const uint8_t* src_u = - static_cast(jni->GetDirectBufferAddress(j_src_u)); + static_cast(jni->GetDirectBufferAddress(j_src_u.obj())); const uint8_t* src_v = - static_cast(jni->GetDirectBufferAddress(j_src_v)); - uint8_t* dst_y = static_cast(jni->GetDirectBufferAddress(j_dst_y)); - uint8_t* dst_u = static_cast(jni->GetDirectBufferAddress(j_dst_u)); - uint8_t* dst_v = static_cast(jni->GetDirectBufferAddress(j_dst_v)); + static_cast(jni->GetDirectBufferAddress(j_src_v.obj())); + uint8_t* dst_y = + static_cast(jni->GetDirectBufferAddress(j_dst_y.obj())); + uint8_t* dst_u = + static_cast(jni->GetDirectBufferAddress(j_dst_u.obj())); + uint8_t* dst_v = + static_cast(jni->GetDirectBufferAddress(j_dst_v.obj())); libyuv::I420Copy(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v, width, height); } -JNI_FUNCTION_DECLARATION(void, - YuvHelper_I420ToNV12, - JNIEnv* jni, - jclass, - jobject j_src_y, - jint src_stride_y, - jobject j_src_u, - jint src_stride_u, - jobject j_src_v, - jint src_stride_v, - jobject j_dst_y, - jint dst_stride_y, - jobject j_dst_uv, - jint dst_stride_uv, - jint width, - jint height) { +static void JNI_YuvHelper_I420ToNV12(JNIEnv* jni, + const JavaParamRef&, + const JavaParamRef& j_src_y, + jint src_stride_y, + const JavaParamRef& j_src_u, + jint src_stride_u, + const JavaParamRef& j_src_v, + jint src_stride_v, + const JavaParamRef& j_dst_y, + jint dst_stride_y, + const JavaParamRef& j_dst_uv, + jint dst_stride_uv, + jint width, + jint height) { const uint8_t* src_y = - static_cast(jni->GetDirectBufferAddress(j_src_y)); + static_cast(jni->GetDirectBufferAddress(j_src_y.obj())); const uint8_t* src_u = - static_cast(jni->GetDirectBufferAddress(j_src_u)); + static_cast(jni->GetDirectBufferAddress(j_src_u.obj())); const uint8_t* src_v = - static_cast(jni->GetDirectBufferAddress(j_src_v)); - uint8_t* dst_y = static_cast(jni->GetDirectBufferAddress(j_dst_y)); + static_cast(jni->GetDirectBufferAddress(j_src_v.obj())); + uint8_t* dst_y = + static_cast(jni->GetDirectBufferAddress(j_dst_y.obj())); uint8_t* dst_uv = - static_cast(jni->GetDirectBufferAddress(j_dst_uv)); + static_cast(jni->GetDirectBufferAddress(j_dst_uv.obj())); libyuv::I420ToNV12(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_y, dst_stride_y, dst_uv, dst_stride_uv,