Android: Generate JNI code for remaining classes in sdk/android

Bug: webrtc:8278
Change-Id: I20a4388ab347d8745d0edde808f7a0b610f077f9
Reviewed-on: https://webrtc-review.googlesource.com/31484
Commit-Queue: Magnus Jedvert <magjed@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21227}
This commit is contained in:
Magnus Jedvert
2017-12-12 12:52:54 +01:00
committed by Commit Bot
parent 1a8fffbb01
commit 9060eb1528
99 changed files with 1553 additions and 1659 deletions

View File

@ -35,6 +35,7 @@ config("libjingle_peerconnection_jni_warnings_config") {
generate_jni("generated_base_jni") { generate_jni("generated_base_jni") {
sources = [ sources = [
"src/java/org/webrtc/JniHelper.java",
"src/java/org/webrtc/WebRtcClassLoader.java", "src/java/org/webrtc/WebRtcClassLoader.java",
] ]
jni_package = "" jni_package = ""
@ -61,19 +62,18 @@ generate_jar_jni("generated_external_classes_jni") {
rtc_source_set("base_jni") { rtc_source_set("base_jni") {
sources = [ sources = [
"src/jni/androidhistogram_jni.cc", "src/jni/androidhistogram.cc",
"src/jni/class_loader.cc", "src/jni/class_loader.cc",
"src/jni/class_loader.h", "src/jni/class_loader.h",
"src/jni/classreferenceholder.cc",
"src/jni/classreferenceholder.h", "src/jni/classreferenceholder.h",
"src/jni/jni_common.cc", "src/jni/jni_common.cc",
"src/jni/jni_generator_helper.cc", "src/jni/jni_generator_helper.cc",
"src/jni/jni_generator_helper.h", "src/jni/jni_generator_helper.h",
"src/jni/jni_helpers.cc", "src/jni/jni_helpers.cc",
"src/jni/jni_helpers.h", "src/jni/jni_helpers.h",
"src/jni/pc/audio_jni.h", "src/jni/pc/audio.h",
"src/jni/pc/media_jni.h", "src/jni/pc/media.h",
"src/jni/pc/video_jni.h", "src/jni/pc/video.h",
] ]
deps = [ deps = [
@ -97,8 +97,8 @@ rtc_source_set("base_jni") {
rtc_static_library("audio_jni") { rtc_static_library("audio_jni") {
sources = [ sources = [
"src/jni/pc/audio_jni.cc", "src/jni/pc/audio.cc",
"src/jni/pc/defaultaudioprocessingfactory_jni.cc", "src/jni/pc/defaultaudioprocessingfactory.cc",
] ]
deps = [ deps = [
@ -113,7 +113,7 @@ rtc_static_library("audio_jni") {
rtc_static_library("null_audio_jni") { rtc_static_library("null_audio_jni") {
sources = [ sources = [
"src/jni/pc/null_audio_jni.cc", "src/jni/pc/null_audio.cc",
] ]
deps = [ deps = [
@ -127,14 +127,19 @@ generate_jni("generated_video_jni") {
"api/org/webrtc/MediaCodecVideoDecoder.java", "api/org/webrtc/MediaCodecVideoDecoder.java",
"api/org/webrtc/MediaCodecVideoEncoder.java", "api/org/webrtc/MediaCodecVideoEncoder.java",
"api/org/webrtc/SurfaceTextureHelper.java", "api/org/webrtc/SurfaceTextureHelper.java",
"api/org/webrtc/VideoCodecInfo.java",
"api/org/webrtc/VideoCodecStatus.java", "api/org/webrtc/VideoCodecStatus.java",
"api/org/webrtc/VideoDecoder.java", "api/org/webrtc/VideoDecoder.java",
"api/org/webrtc/VideoDecoderFactory.java",
"api/org/webrtc/VideoEncoder.java", "api/org/webrtc/VideoEncoder.java",
"api/org/webrtc/VideoEncoderFactory.java", "api/org/webrtc/VideoEncoderFactory.java",
"api/org/webrtc/VideoFrame.java", "api/org/webrtc/VideoFrame.java",
"api/org/webrtc/VideoRenderer.java",
"api/org/webrtc/VideoSink.java", "api/org/webrtc/VideoSink.java",
"src/java/org/webrtc/EglBase14.java",
"src/java/org/webrtc/VideoDecoderWrapper.java", "src/java/org/webrtc/VideoDecoderWrapper.java",
"src/java/org/webrtc/VideoEncoderWrapper.java", "src/java/org/webrtc/VideoEncoderWrapper.java",
"src/java/org/webrtc/WrappedNativeI420Buffer.java",
"src/java/org/webrtc/WrappedNativeVideoDecoder.java", "src/java/org/webrtc/WrappedNativeVideoDecoder.java",
"src/java/org/webrtc/WrappedNativeVideoEncoder.java", "src/java/org/webrtc/WrappedNativeVideoEncoder.java",
] ]
@ -145,23 +150,22 @@ generate_jni("generated_video_jni") {
rtc_static_library("video_jni") { rtc_static_library("video_jni") {
sources = [ sources = [
"src/jni/androidmediacodeccommon.h", "src/jni/androidmediacodeccommon.h",
"src/jni/androidmediadecoder_jni.cc", "src/jni/androidmediadecoder.cc",
"src/jni/androidmediadecoder_jni.h", "src/jni/androidmediadecoder_jni.h",
"src/jni/androidmediaencoder_jni.cc", "src/jni/androidmediaencoder.cc",
"src/jni/androidmediaencoder_jni.h", "src/jni/androidmediaencoder_jni.h",
"src/jni/androidvideotracksource.cc", "src/jni/androidvideotracksource.cc",
"src/jni/androidvideotracksource.h", "src/jni/androidvideotracksource.h",
"src/jni/androidvideotracksource_jni.cc",
"src/jni/encodedimage.cc", "src/jni/encodedimage.cc",
"src/jni/encodedimage.h", "src/jni/encodedimage.h",
"src/jni/hardwarevideoencoderfactory.cc", "src/jni/hardwarevideoencoderfactory.cc",
"src/jni/jni_generator_helper.h", "src/jni/jni_generator_helper.h",
"src/jni/nv12buffer_jni.cc", "src/jni/nv12buffer.cc",
"src/jni/nv21buffer_jni.cc", "src/jni/nv21buffer.cc",
"src/jni/pc/video_jni.cc", "src/jni/pc/video.cc",
"src/jni/surfacetexturehelper_jni.cc", "src/jni/surfacetexturehelper.cc",
"src/jni/surfacetexturehelper_jni.h", "src/jni/surfacetexturehelper.h",
"src/jni/video_renderer_jni.cc", "src/jni/video_renderer.cc",
"src/jni/videocodecinfo.cc", "src/jni/videocodecinfo.cc",
"src/jni/videocodecinfo.h", "src/jni/videocodecinfo.h",
"src/jni/videocodecstatus.cc", "src/jni/videocodecstatus.cc",
@ -176,10 +180,10 @@ rtc_static_library("video_jni") {
"src/jni/videoencoderfallback.cc", "src/jni/videoencoderfallback.cc",
"src/jni/videoencoderwrapper.cc", "src/jni/videoencoderwrapper.cc",
"src/jni/videoencoderwrapper.h", "src/jni/videoencoderwrapper.h",
"src/jni/videofilerenderer_jni.cc", "src/jni/videofilerenderer.cc",
"src/jni/videoframe.cc", "src/jni/videoframe.cc",
"src/jni/videoframe.h", "src/jni/videoframe.h",
"src/jni/videotrack_jni.cc", "src/jni/videotrack.cc",
"src/jni/vp8codec.cc", "src/jni/vp8codec.cc",
"src/jni/vp9codec.cc", "src/jni/vp9codec.cc",
"src/jni/wrapped_native_i420_buffer.cc", "src/jni/wrapped_native_i420_buffer.cc",
@ -239,7 +243,7 @@ rtc_static_library("video_jni") {
rtc_static_library("null_video_jni") { rtc_static_library("null_video_jni") {
sources = [ sources = [
"src/jni/pc/null_video_jni.cc", "src/jni/pc/null_video.cc",
] ]
deps = [ deps = [
@ -249,7 +253,7 @@ rtc_static_library("null_video_jni") {
rtc_static_library("media_jni") { rtc_static_library("media_jni") {
sources = [ sources = [
"src/jni/pc/media_jni.cc", "src/jni/pc/media.cc",
] ]
deps = [ deps = [
@ -273,7 +277,7 @@ rtc_static_library("media_jni") {
rtc_static_library("null_media_jni") { rtc_static_library("null_media_jni") {
sources = [ sources = [
"src/jni/pc/null_media_jni.cc", "src/jni/pc/null_media.cc",
] ]
deps = [ deps = [
@ -294,18 +298,24 @@ generate_jni("generated_peerconnection_jni") {
"api/org/webrtc/DataChannel.java", "api/org/webrtc/DataChannel.java",
"api/org/webrtc/IceCandidate.java", "api/org/webrtc/IceCandidate.java",
"api/org/webrtc/MediaConstraints.java", "api/org/webrtc/MediaConstraints.java",
"api/org/webrtc/MediaSource.java",
"api/org/webrtc/MediaStream.java", "api/org/webrtc/MediaStream.java",
"api/org/webrtc/MediaStreamTrack.java", "api/org/webrtc/MediaStreamTrack.java",
"api/org/webrtc/NetworkMonitor.java", "api/org/webrtc/NetworkMonitor.java",
"api/org/webrtc/NetworkMonitorAutoDetect.java", "api/org/webrtc/NetworkMonitorAutoDetect.java",
"api/org/webrtc/PeerConnection.java", "api/org/webrtc/PeerConnection.java",
"api/org/webrtc/PeerConnectionFactory.java",
"api/org/webrtc/RTCStats.java", "api/org/webrtc/RTCStats.java",
"api/org/webrtc/RTCStatsCollectorCallback.java", "api/org/webrtc/RTCStatsCollectorCallback.java",
"api/org/webrtc/RTCStatsReport.java", "api/org/webrtc/RTCStatsReport.java",
"api/org/webrtc/RtpParameters.java",
"api/org/webrtc/RtpReceiver.java", "api/org/webrtc/RtpReceiver.java",
"api/org/webrtc/RtpSender.java", "api/org/webrtc/RtpSender.java",
"api/org/webrtc/SdpObserver.java",
"api/org/webrtc/SessionDescription.java",
"api/org/webrtc/StatsObserver.java", "api/org/webrtc/StatsObserver.java",
"api/org/webrtc/StatsReport.java", "api/org/webrtc/StatsReport.java",
"api/org/webrtc/TurnCustomizer.java",
] ]
jni_package = "" jni_package = ""
jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h" jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h"
@ -314,35 +324,42 @@ generate_jni("generated_peerconnection_jni") {
rtc_static_library("peerconnection_jni") { rtc_static_library("peerconnection_jni") {
sources = [ sources = [
"src/jni/androidnetworkmonitor_jni.h", "src/jni/androidnetworkmonitor_jni.h",
"src/jni/pc/androidnetworkmonitor_jni.cc", "src/jni/pc/androidnetworkmonitor.cc",
"src/jni/pc/androidnetworkmonitor_jni.h", "src/jni/pc/androidnetworkmonitor.h",
"src/jni/pc/audiotrack_jni.cc", "src/jni/pc/audiotrack.cc",
"src/jni/pc/callsessionfilerotatinglogsink_jni.cc", "src/jni/pc/callsessionfilerotatinglogsink.cc",
"src/jni/pc/datachannel.cc", "src/jni/pc/datachannel.cc",
"src/jni/pc/datachannel.h", "src/jni/pc/datachannel.h",
"src/jni/pc/dtmfsender_jni.cc", "src/jni/pc/dtmfsender.cc",
"src/jni/pc/java_native_conversion.cc", "src/jni/pc/icecandidate.cc",
"src/jni/pc/java_native_conversion.h", "src/jni/pc/icecandidate.h",
"src/jni/pc/logging_jni.cc", "src/jni/pc/logging.cc",
"src/jni/pc/mediaconstraints_jni.cc", "src/jni/pc/mediaconstraints.cc",
"src/jni/pc/mediaconstraints_jni.h", "src/jni/pc/mediaconstraints.h",
"src/jni/pc/mediasource_jni.cc", "src/jni/pc/mediasource.cc",
"src/jni/pc/mediastream_jni.cc", "src/jni/pc/mediastream.cc",
"src/jni/pc/mediastreamtrack_jni.cc", "src/jni/pc/mediastreamtrack.cc",
"src/jni/pc/mediastreamtrack.h",
"src/jni/pc/ownedfactoryandthreads.cc", "src/jni/pc/ownedfactoryandthreads.cc",
"src/jni/pc/ownedfactoryandthreads.h", "src/jni/pc/ownedfactoryandthreads.h",
"src/jni/pc/peerconnection.cc", "src/jni/pc/peerconnection.cc",
"src/jni/pc/peerconnection.h", "src/jni/pc/peerconnection.h",
"src/jni/pc/peerconnectionfactory_jni.cc", "src/jni/pc/peerconnectionfactory.cc",
"src/jni/pc/peerconnectionfactory.h",
"src/jni/pc/rtcstatscollectorcallbackwrapper.cc", "src/jni/pc/rtcstatscollectorcallbackwrapper.cc",
"src/jni/pc/rtcstatscollectorcallbackwrapper.h", "src/jni/pc/rtcstatscollectorcallbackwrapper.h",
"src/jni/pc/rtpparameters.cc",
"src/jni/pc/rtpparameters.h",
"src/jni/pc/rtpreceiver.cc", "src/jni/pc/rtpreceiver.cc",
"src/jni/pc/rtpreceiver.h", "src/jni/pc/rtpreceiver.h",
"src/jni/pc/rtpsender_jni.cc", "src/jni/pc/rtpsender.cc",
"src/jni/pc/sdpobserver_jni.h", "src/jni/pc/sdpobserver.cc",
"src/jni/pc/statsobserver_jni.cc", "src/jni/pc/sdpobserver.h",
"src/jni/pc/statsobserver_jni.h", "src/jni/pc/sessiondescription.cc",
"src/jni/pc/turncustomizer_jni.cc", "src/jni/pc/sessiondescription.h",
"src/jni/pc/statsobserver.cc",
"src/jni/pc/statsobserver.h",
"src/jni/pc/turncustomizer.cc",
] ]
configs += [ ":libjingle_peerconnection_jni_warnings_config" ] configs += [ ":libjingle_peerconnection_jni_warnings_config" ]
@ -406,7 +423,7 @@ generate_jni("generated_metrics_jni") {
rtc_static_library("libjingle_peerconnection_metrics_default_jni") { rtc_static_library("libjingle_peerconnection_metrics_default_jni") {
sources = [ sources = [
"src/jni/androidmetrics_jni.cc", "src/jni/androidmetrics.cc",
] ]
configs += [ ":libjingle_peerconnection_jni_warnings_config" ] configs += [ ":libjingle_peerconnection_jni_warnings_config" ]
@ -617,6 +634,7 @@ rtc_android_library("libjingle_peerconnection_java") {
"src/java/org/webrtc/CameraCapturer.java", "src/java/org/webrtc/CameraCapturer.java",
"src/java/org/webrtc/CameraSession.java", "src/java/org/webrtc/CameraSession.java",
"src/java/org/webrtc/WebRtcClassLoader.java", "src/java/org/webrtc/WebRtcClassLoader.java",
"src/java/org/webrtc/JniHelper.java",
"src/java/org/webrtc/DynamicBitrateAdjuster.java", "src/java/org/webrtc/DynamicBitrateAdjuster.java",
"src/java/org/webrtc/EglBase10.java", "src/java/org/webrtc/EglBase10.java",
"src/java/org/webrtc/EglBase14.java", "src/java/org/webrtc/EglBase14.java",

View File

@ -28,7 +28,7 @@ import java.util.Set;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
// Java-side of peerconnection_jni.cc:MediaCodecVideoDecoder. // Java-side of peerconnection.cc:MediaCodecVideoDecoder.
// This class is an implementation detail of the Java PeerConnection API. // This class is an implementation detail of the Java PeerConnection API.
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class MediaCodecVideoDecoder { public class MediaCodecVideoDecoder {

View File

@ -32,7 +32,7 @@ import java.util.concurrent.TimeUnit;
import org.webrtc.EglBase14; import org.webrtc.EglBase14;
import org.webrtc.VideoFrame; import org.webrtc.VideoFrame;
// Java-side of peerconnection_jni.cc:MediaCodecVideoEncoder. // Java-side of peerconnection.cc:MediaCodecVideoEncoder.
// This class is an implementation detail of the Java PeerConnection API. // This class is an implementation detail of the Java PeerConnection API.
@TargetApi(19) @TargetApi(19)
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@ -658,7 +658,7 @@ public class MediaCodecVideoEncoder {
if (dataV.capacity() < strideV * chromaHeight) { if (dataV.capacity() < strideV * chromaHeight) {
throw new RuntimeException("V-plane buffer size too small."); throw new RuntimeException("V-plane buffer size too small.");
} }
fillNativeBuffer( fillInputBufferNative(
nativeEncoder, bufferIndex, dataY, strideY, dataU, strideU, dataV, strideV); nativeEncoder, bufferIndex, dataY, strideY, dataU, strideU, dataV, strideV);
i420Buffer.release(); i420Buffer.release();
// I420 consists of one full-resolution and two half-resolution planes. // I420 consists of one full-resolution and two half-resolution planes.
@ -993,6 +993,6 @@ public class MediaCodecVideoEncoder {
} }
/** Fills an inputBuffer with the given index with data from the byte buffers. */ /** Fills an inputBuffer with the given index with data from the byte buffers. */
private static native void fillNativeBuffer(long nativeEncoder, int inputBuffer, ByteBuffer dataY, private static native void fillInputBufferNative(long nativeEncoder, int inputBuffer,
int strideY, ByteBuffer dataU, int strideU, ByteBuffer dataV, int strideV); ByteBuffer dataY, int strideY, ByteBuffer dataU, int strideU, ByteBuffer dataV, int strideV);
} }

View File

@ -13,7 +13,17 @@ package org.webrtc;
/** Java wrapper for a C++ MediaSourceInterface. */ /** Java wrapper for a C++ MediaSourceInterface. */
public class MediaSource { public class MediaSource {
/** Tracks MediaSourceInterface.SourceState */ /** Tracks MediaSourceInterface.SourceState */
public enum State { INITIALIZING, LIVE, ENDED, MUTED } public enum State {
INITIALIZING,
LIVE,
ENDED,
MUTED;
@CalledByNative("State")
static State fromNativeIndex(int nativeIndex) {
return values()[nativeIndex];
}
}
final long nativeSource; // Package-protected for PeerConnectionFactory. final long nativeSource; // Package-protected for PeerConnectionFactory.
@ -22,12 +32,12 @@ public class MediaSource {
} }
public State state() { public State state() {
return nativeState(nativeSource); return getNativeState(nativeSource);
} }
public void dispose() { public void dispose() {
JniCommon.nativeReleaseRef(nativeSource); JniCommon.nativeReleaseRef(nativeSource);
} }
private static native State nativeState(long pointer); private static native State getNativeState(long pointer);
} }

View File

@ -13,7 +13,15 @@ package org.webrtc;
/** Java wrapper for a C++ MediaStreamTrackInterface. */ /** Java wrapper for a C++ MediaStreamTrackInterface. */
public class MediaStreamTrack { public class MediaStreamTrack {
/** Tracks MediaStreamTrackInterface.TrackState */ /** Tracks MediaStreamTrackInterface.TrackState */
public enum State { LIVE, ENDED } public enum State {
LIVE,
ENDED;
@CalledByNative("State")
static State fromNativeIndex(int nativeIndex) {
return values()[nativeIndex];
}
}
// Must be kept in sync with cricket::MediaType. // Must be kept in sync with cricket::MediaType.
public enum MediaType { public enum MediaType {

View File

@ -13,7 +13,7 @@ package org.webrtc;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
// Java-side of androidmetrics_jni.cc. // Java-side of androidmetrics.cc
// //
// Rtc histograms can be queried through the API, getAndReset(). // Rtc histograms can be queried through the API, getAndReset().
// The returned map holds the name of a histogram and its samples. // The returned map holds the name of a histogram and its samples.

View File

@ -251,6 +251,41 @@ public class PeerConnection {
tlsAlpnProtocols, tlsEllipticCurves); tlsAlpnProtocols, tlsEllipticCurves);
} }
} }
@CalledByNative("IceServer")
List<String> getUrls() {
return urls;
}
@CalledByNative("IceServer")
String getUsername() {
return username;
}
@CalledByNative("IceServer")
String getPassword() {
return password;
}
@CalledByNative("IceServer")
TlsCertPolicy getTlsCertPolicy() {
return tlsCertPolicy;
}
@CalledByNative("IceServer")
String getHostname() {
return hostname;
}
@CalledByNative("IceServer")
List<String> getTlsAlpnProtocols() {
return tlsAlpnProtocols;
}
@CalledByNative("IceServer")
List<String> getTlsEllipticCurves() {
return tlsEllipticCurves;
}
} }
/** Java version of PeerConnectionInterface.IceTransportsType */ /** Java version of PeerConnectionInterface.IceTransportsType */
@ -284,10 +319,12 @@ public class PeerConnection {
this.max = max; this.max = max;
} }
@CalledByNative("IntervalRange")
public int getMin() { public int getMin() {
return min; return min;
} }
@CalledByNative("IntervalRange")
public int getMax() { public int getMax() {
return max; return max;
} }
@ -347,6 +384,106 @@ public class PeerConnection {
maxIPv6Networks = 5; maxIPv6Networks = 5;
iceRegatherIntervalRange = null; iceRegatherIntervalRange = null;
} }
@CalledByNative("RTCConfiguration")
IceTransportsType getIceTransportsType() {
return iceTransportsType;
}
@CalledByNative("RTCConfiguration")
List<IceServer> getIceServers() {
return iceServers;
}
@CalledByNative("RTCConfiguration")
BundlePolicy getBundlePolicy() {
return bundlePolicy;
}
@CalledByNative("RTCConfiguration")
RtcpMuxPolicy getRtcpMuxPolicy() {
return rtcpMuxPolicy;
}
@CalledByNative("RTCConfiguration")
TcpCandidatePolicy getTcpCandidatePolicy() {
return tcpCandidatePolicy;
}
@CalledByNative("RTCConfiguration")
CandidateNetworkPolicy getCandidateNetworkPolicy() {
return candidateNetworkPolicy;
}
@CalledByNative("RTCConfiguration")
int getAudioJitterBufferMaxPackets() {
return audioJitterBufferMaxPackets;
}
@CalledByNative("RTCConfiguration")
boolean getAudioJitterBufferFastAccelerate() {
return audioJitterBufferFastAccelerate;
}
@CalledByNative("RTCConfiguration")
int getIceConnectionReceivingTimeout() {
return iceConnectionReceivingTimeout;
}
@CalledByNative("RTCConfiguration")
int getIceBackupCandidatePairPingInterval() {
return iceBackupCandidatePairPingInterval;
}
@CalledByNative("RTCConfiguration")
KeyType getKeyType() {
return keyType;
}
@CalledByNative("RTCConfiguration")
ContinualGatheringPolicy getContinualGatheringPolicy() {
return continualGatheringPolicy;
}
@CalledByNative("RTCConfiguration")
int getIceCandidatePoolSize() {
return iceCandidatePoolSize;
}
@CalledByNative("RTCConfiguration")
boolean getPruneTurnPorts() {
return pruneTurnPorts;
}
@CalledByNative("RTCConfiguration")
boolean getPresumeWritableWhenFullyRelayed() {
return presumeWritableWhenFullyRelayed;
}
@CalledByNative("RTCConfiguration")
Integer getIceCheckMinInterval() {
return iceCheckMinInterval;
}
@CalledByNative("RTCConfiguration")
boolean getDisableIPv6OnWifi() {
return disableIPv6OnWifi;
}
@CalledByNative("RTCConfiguration")
int getMaxIPv6Networks() {
return maxIPv6Networks;
}
@CalledByNative("RTCConfiguration")
IntervalRange getIceRegatherIntervalRange() {
return iceRegatherIntervalRange;
}
@CalledByNative("RTCConfiguration")
TurnCustomizer getTurnCustomizer() {
return turnCustomizer;
}
}; };
private final List<MediaStream> localStreams = new ArrayList<>(); private final List<MediaStream> localStreams = new ArrayList<>();
@ -552,6 +689,11 @@ public class PeerConnection {
freeObserver(nativeObserver); freeObserver(nativeObserver);
} }
@CalledByNative
long getNativePeerConnection() {
return nativePeerConnection;
}
private static native void freeObserver(long nativeObserver); private static native void freeObserver(long nativeObserver);
private native boolean setNativeConfiguration(RTCConfiguration config, long nativeObserver); private native boolean setNativeConfiguration(RTCConfiguration config, long nativeObserver);

View File

@ -104,6 +104,21 @@ public class PeerConnectionFactory {
public int networkIgnoreMask; public int networkIgnoreMask;
public boolean disableEncryption; public boolean disableEncryption;
public boolean disableNetworkMonitor; public boolean disableNetworkMonitor;
@CalledByNative("Options")
int getNetworkIgnoreMask() {
return networkIgnoreMask;
}
@CalledByNative("Options")
boolean getDisableEncryption() {
return disableEncryption;
}
@CalledByNative("Options")
boolean getDisableNetworkMonitor() {
return disableNetworkMonitor;
}
} }
/** /**
@ -114,7 +129,7 @@ public class PeerConnectionFactory {
public static void initialize(InitializationOptions options) { public static void initialize(InitializationOptions options) {
ContextUtils.initialize(options.applicationContext); ContextUtils.initialize(options.applicationContext);
NativeLibrary.initialize(options.nativeLibraryLoader); NativeLibrary.initialize(options.nativeLibraryLoader);
nativeInitializeAndroidGlobals(options.applicationContext, options.enableVideoHwAcceleration); initializeNativeAndroidGlobals(options.applicationContext, options.enableVideoHwAcceleration);
initializeFieldTrials(options.fieldTrials); initializeFieldTrials(options.fieldTrials);
if (options.enableInternalTracer && !internalTracerInitialized) { if (options.enableInternalTracer && !internalTracerInitialized) {
initializeInternalTracer(); initializeInternalTracer();
@ -131,17 +146,17 @@ public class PeerConnectionFactory {
// Must be called at least once before creating a PeerConnectionFactory // Must be called at least once before creating a PeerConnectionFactory
// (for example, at application startup time). // (for example, at application startup time).
private static native void nativeInitializeAndroidGlobals( private static native void initializeNativeAndroidGlobals(
Context context, boolean videoHwAcceleration); Context context, boolean videoHwAcceleration);
private static void initializeInternalTracer() { private static void initializeInternalTracer() {
internalTracerInitialized = true; internalTracerInitialized = true;
nativeInitializeInternalTracer(); initializeNativeInternalTracer();
} }
public static void shutdownInternalTracer() { public static void shutdownInternalTracer() {
internalTracerInitialized = false; internalTracerInitialized = false;
nativeShutdownInternalTracer(); shutdownNativeInternalTracer();
} }
// Field trial initialization. Must be called before PeerConnectionFactory // Field trial initialization. Must be called before PeerConnectionFactory
@ -156,16 +171,16 @@ public class PeerConnectionFactory {
// method2(); // method2();
// } // }
public static String fieldTrialsFindFullName(String name) { public static String fieldTrialsFindFullName(String name) {
return NativeLibrary.isLoaded() ? nativeFieldTrialsFindFullName(name) : ""; return NativeLibrary.isLoaded() ? findNativeFieldTrialsFullName(name) : "";
} }
private static native String nativeFieldTrialsFindFullName(String name); private static native String findNativeFieldTrialsFullName(String name);
// Internal tracing initialization. Must be called before PeerConnectionFactory is created to // Internal tracing initialization. Must be called before PeerConnectionFactory is created to
// prevent racing with tracing code. // prevent racing with tracing code.
// Deprecated, use PeerConnectionFactory.initialize instead. // Deprecated, use PeerConnectionFactory.initialize instead.
private static native void nativeInitializeInternalTracer(); private static native void initializeNativeInternalTracer();
// Internal tracing shutdown, called to prevent resource leaks. Must be called after // Internal tracing shutdown, called to prevent resource leaks. Must be called after
// PeerConnectionFactory is gone to prevent races with code performing tracing. // PeerConnectionFactory is gone to prevent races with code performing tracing.
private static native void nativeShutdownInternalTracer(); private static native void shutdownNativeInternalTracer();
// Start/stop internal capturing of internal tracing. // Start/stop internal capturing of internal tracing.
public static native boolean startInternalTracingCapture(String tracing_filename); public static native boolean startInternalTracingCapture(String tracing_filename);
public static native void stopInternalTracingCapture(); public static native void stopInternalTracingCapture();
@ -184,7 +199,7 @@ public class PeerConnectionFactory {
public PeerConnectionFactory( public PeerConnectionFactory(
Options options, VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory) { Options options, VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory) {
checkInitializeHasBeenCalled(); checkInitializeHasBeenCalled();
nativeFactory = nativeCreatePeerConnectionFactory(options, encoderFactory, decoderFactory); nativeFactory = createNativePeerConnectionFactory(options, encoderFactory, decoderFactory);
if (nativeFactory == 0) { if (nativeFactory == 0) {
throw new RuntimeException("Failed to initialize PeerConnectionFactory!"); throw new RuntimeException("Failed to initialize PeerConnectionFactory!");
} }
@ -197,7 +212,7 @@ public class PeerConnectionFactory {
throw new NullPointerException( throw new NullPointerException(
"PeerConnectionFactory constructor does not accept a null AudioProcessingFactory."); "PeerConnectionFactory constructor does not accept a null AudioProcessingFactory.");
} }
nativeFactory = nativeCreatePeerConnectionFactoryWithAudioProcessing( nativeFactory = createNativePeerConnectionFactoryWithAudioProcessing(
options, encoderFactory, decoderFactory, audioProcessingFactory.createNative()); options, encoderFactory, decoderFactory, audioProcessingFactory.createNative());
if (nativeFactory == 0) { if (nativeFactory == 0) {
throw new RuntimeException("Failed to initialize PeerConnectionFactory!"); throw new RuntimeException("Failed to initialize PeerConnectionFactory!");
@ -206,12 +221,12 @@ public class PeerConnectionFactory {
public PeerConnection createPeerConnection(PeerConnection.RTCConfiguration rtcConfig, public PeerConnection createPeerConnection(PeerConnection.RTCConfiguration rtcConfig,
MediaConstraints constraints, PeerConnection.Observer observer) { MediaConstraints constraints, PeerConnection.Observer observer) {
long nativeObserver = nativeCreateObserver(observer); long nativeObserver = createNativeObserver(observer);
if (nativeObserver == 0) { if (nativeObserver == 0) {
return null; return null;
} }
long nativePeerConnection = long nativePeerConnection =
nativeCreatePeerConnection(nativeFactory, rtcConfig, constraints, nativeObserver); createNativePeerConnection(nativeFactory, rtcConfig, constraints, nativeObserver);
if (nativePeerConnection == 0) { if (nativePeerConnection == 0) {
return null; return null;
} }
@ -225,7 +240,7 @@ public class PeerConnectionFactory {
} }
public MediaStream createLocalMediaStream(String label) { public MediaStream createLocalMediaStream(String label) {
return new MediaStream(nativeCreateLocalMediaStream(nativeFactory, label)); return new MediaStream(createNativeLocalMediaStream(nativeFactory, label));
} }
public VideoSource createVideoSource(VideoCapturer capturer) { public VideoSource createVideoSource(VideoCapturer capturer) {
@ -234,7 +249,7 @@ public class PeerConnectionFactory {
final SurfaceTextureHelper surfaceTextureHelper = final SurfaceTextureHelper surfaceTextureHelper =
SurfaceTextureHelper.create(VIDEO_CAPTURER_THREAD_NAME, eglContext); SurfaceTextureHelper.create(VIDEO_CAPTURER_THREAD_NAME, eglContext);
long nativeAndroidVideoTrackSource = long nativeAndroidVideoTrackSource =
nativeCreateVideoSource(nativeFactory, surfaceTextureHelper, capturer.isScreencast()); createNativeVideoSource(nativeFactory, surfaceTextureHelper, capturer.isScreencast());
VideoCapturer.CapturerObserver capturerObserver = VideoCapturer.CapturerObserver capturerObserver =
new AndroidVideoTrackSourceObserver(nativeAndroidVideoTrackSource); new AndroidVideoTrackSourceObserver(nativeAndroidVideoTrackSource);
capturer.initialize( capturer.initialize(
@ -243,33 +258,33 @@ public class PeerConnectionFactory {
} }
public VideoTrack createVideoTrack(String id, VideoSource source) { public VideoTrack createVideoTrack(String id, VideoSource source) {
return new VideoTrack(nativeCreateVideoTrack(nativeFactory, id, source.nativeSource)); return new VideoTrack(createNativeVideoTrack(nativeFactory, id, source.nativeSource));
} }
public AudioSource createAudioSource(MediaConstraints constraints) { public AudioSource createAudioSource(MediaConstraints constraints) {
return new AudioSource(nativeCreateAudioSource(nativeFactory, constraints)); return new AudioSource(createNativeAudioSource(nativeFactory, constraints));
} }
public AudioTrack createAudioTrack(String id, AudioSource source) { public AudioTrack createAudioTrack(String id, AudioSource source) {
return new AudioTrack(nativeCreateAudioTrack(nativeFactory, id, source.nativeSource)); return new AudioTrack(createNativeAudioTrack(nativeFactory, id, source.nativeSource));
} }
// Starts recording an AEC dump. Ownership of the file is transfered to the // 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 // native code. If an AEC dump is already in progress, it will be stopped and
// a new one will start using the provided file. // a new one will start using the provided file.
public boolean startAecDump(int file_descriptor, int filesize_limit_bytes) { public boolean startAecDump(int file_descriptor, int filesize_limit_bytes) {
return nativeStartAecDump(nativeFactory, file_descriptor, filesize_limit_bytes); return startNativeAecDump(nativeFactory, file_descriptor, filesize_limit_bytes);
} }
// Stops recording an AEC dump. If no AEC dump is currently being recorded, // Stops recording an AEC dump. If no AEC dump is currently being recorded,
// this call will have no effect. // this call will have no effect.
public void stopAecDump() { public void stopAecDump() {
nativeStopAecDump(nativeFactory); stopNativeAecDump(nativeFactory);
} }
@Deprecated @Deprecated
public void setOptions(Options options) { public void setOptions(Options options) {
nativeSetOptions(nativeFactory, options); setNativeOptions(nativeFactory, options);
} }
/** Set the EGL context used by HW Video encoding and decoding. /** Set the EGL context used by HW Video encoding and decoding.
@ -290,12 +305,12 @@ public class PeerConnectionFactory {
} }
localEglbase = EglBase.create(localEglContext); localEglbase = EglBase.create(localEglContext);
remoteEglbase = EglBase.create(remoteEglContext); remoteEglbase = EglBase.create(remoteEglContext);
nativeSetVideoHwAccelerationOptions( setNativeVideoHwAccelerationOptions(
nativeFactory, localEglbase.getEglBaseContext(), remoteEglbase.getEglBaseContext()); nativeFactory, localEglbase.getEglBaseContext(), remoteEglbase.getEglBaseContext());
} }
public void dispose() { public void dispose() {
nativeFreeFactory(nativeFactory); freeNativeFactory(nativeFactory);
networkThread = null; networkThread = null;
workerThread = null; workerThread = null;
signalingThread = null; signalingThread = null;
@ -306,7 +321,7 @@ public class PeerConnectionFactory {
} }
public void threadsCallbacks() { public void threadsCallbacks() {
nativeThreadsCallbacks(nativeFactory); invokeNativeThreadsCallbacks(nativeFactory);
} }
private static void printStackTrace(Thread thread, String threadName) { private static void printStackTrace(Thread thread, String threadName) {
@ -327,58 +342,66 @@ public class PeerConnectionFactory {
printStackTrace(signalingThread, "Signaling thread"); printStackTrace(signalingThread, "Signaling thread");
} }
@CalledByNative
private static void onNetworkThreadReady() { private static void onNetworkThreadReady() {
networkThread = Thread.currentThread(); networkThread = Thread.currentThread();
Logging.d(TAG, "onNetworkThreadReady"); Logging.d(TAG, "onNetworkThreadReady");
} }
@CalledByNative
private static void onWorkerThreadReady() { private static void onWorkerThreadReady() {
workerThread = Thread.currentThread(); workerThread = Thread.currentThread();
Logging.d(TAG, "onWorkerThreadReady"); Logging.d(TAG, "onWorkerThreadReady");
} }
@CalledByNative
private static void onSignalingThreadReady() { private static void onSignalingThreadReady() {
signalingThread = Thread.currentThread(); signalingThread = Thread.currentThread();
Logging.d(TAG, "onSignalingThreadReady"); Logging.d(TAG, "onSignalingThreadReady");
} }
private static native long nativeCreatePeerConnectionFactory( private static native long createNativePeerConnectionFactory(
Options options, VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory); Options options, VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory);
private static native long nativeCreatePeerConnectionFactoryWithAudioProcessing(Options options, private static native long createNativePeerConnectionFactoryWithAudioProcessing(Options options,
VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory, VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory,
long nativeAudioProcessor); long nativeAudioProcessor);
private static native long nativeCreateObserver(PeerConnection.Observer observer); private static native long createNativeObserver(PeerConnection.Observer observer);
private static native long nativeCreatePeerConnection(long nativeFactory, private static native long createNativePeerConnection(long nativeFactory,
PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, long nativeObserver); PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, long nativeObserver);
private static native long nativeCreateLocalMediaStream(long nativeFactory, String label); private static native long createNativeLocalMediaStream(long nativeFactory, String label);
private static native long nativeCreateVideoSource( private static native long createNativeVideoSource(
long nativeFactory, SurfaceTextureHelper surfaceTextureHelper, boolean is_screencast); long nativeFactory, SurfaceTextureHelper surfaceTextureHelper, boolean is_screencast);
private static native long nativeCreateVideoTrack( private static native long createNativeVideoTrack(
long nativeFactory, String id, long nativeVideoSource); long nativeFactory, String id, long nativeVideoSource);
private static native long nativeCreateAudioSource( private static native long createNativeAudioSource(
long nativeFactory, MediaConstraints constraints); long nativeFactory, MediaConstraints constraints);
private static native long nativeCreateAudioTrack( private static native long createNativeAudioTrack(
long nativeFactory, String id, long nativeSource); long nativeFactory, String id, long nativeSource);
private static native boolean nativeStartAecDump( private static native boolean startNativeAecDump(
long nativeFactory, int file_descriptor, int filesize_limit_bytes); long nativeFactory, int file_descriptor, int filesize_limit_bytes);
private static native void nativeStopAecDump(long nativeFactory); private static native void stopNativeAecDump(long nativeFactory);
@Deprecated public native void nativeSetOptions(long nativeFactory, Options options); @Deprecated
public void nativeSetOptions(long nativeFactory, Options options) {
setNativeOptions(nativeFactory, options);
}
private static native void nativeSetVideoHwAccelerationOptions( private native void setNativeOptions(long nativeFactory, Options options);
private static native void setNativeVideoHwAccelerationOptions(
long nativeFactory, Object localEGLContext, Object remoteEGLContext); long nativeFactory, Object localEGLContext, Object remoteEGLContext);
private static native void nativeThreadsCallbacks(long nativeFactory); private static native void invokeNativeThreadsCallbacks(long nativeFactory);
private static native void nativeFreeFactory(long nativeFactory); private static native void freeNativeFactory(long nativeFactory);
} }

View File

@ -12,6 +12,7 @@ package org.webrtc;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import org.webrtc.MediaStreamTrack;
/** /**
* The parameters for an {@code RtpSender}, as defined in * The parameters for an {@code RtpSender}, as defined in
@ -34,6 +35,28 @@ public class RtpParameters {
// SSRC to be used by this encoding. // SSRC to be used by this encoding.
// Can't be changed between getParameters/setParameters. // Can't be changed between getParameters/setParameters.
public Long ssrc; public Long ssrc;
@CalledByNative("Encoding")
Encoding(boolean active, Integer maxBitrateBps, Long ssrc) {
this.active = active;
this.maxBitrateBps = maxBitrateBps;
this.ssrc = ssrc;
}
@CalledByNative("Encoding")
boolean getActive() {
return active;
}
@CalledByNative("Encoding")
Integer getMaxBitrateBps() {
return maxBitrateBps;
}
@CalledByNative("Encoding")
Long getSsrc() {
return ssrc;
}
} }
public static class Codec { public static class Codec {
@ -47,11 +70,67 @@ public class RtpParameters {
public Integer clockRate; public Integer clockRate;
// The number of audio channels used. Set to null for video codecs. // The number of audio channels used. Set to null for video codecs.
public Integer numChannels; public Integer numChannels;
@CalledByNative("Codec")
Codec(int payloadType, String name, MediaStreamTrack.MediaType kind, Integer clockRate,
Integer numChannels) {
this.payloadType = payloadType;
this.name = name;
this.kind = kind;
this.clockRate = clockRate;
this.numChannels = numChannels;
}
@CalledByNative("Codec")
int getPayloadType() {
return payloadType;
}
@CalledByNative("Codec")
String getName() {
return name;
}
@CalledByNative("Codec")
MediaStreamTrack.MediaType getKind() {
return kind;
}
@CalledByNative("Codec")
Integer getClockRate() {
return clockRate;
}
@CalledByNative("Codec")
Integer getNumChannels() {
return numChannels;
}
} }
public final List<Encoding> encodings = new ArrayList<>(); public final List<Encoding> encodings;
// Codec parameters can't currently be changed between getParameters and // Codec parameters can't currently be changed between getParameters and
// setParameters. Though in the future it will be possible to reorder them or // setParameters. Though in the future it will be possible to reorder them or
// remove them. // remove them.
public final List<Codec> codecs = new ArrayList<>(); public final List<Codec> codecs;
public RtpParameters() {
this.encodings = new ArrayList<>();
this.codecs = new ArrayList<>();
}
@CalledByNative
RtpParameters(List<Encoding> encodings, List<Codec> codecs) {
this.encodings = encodings;
this.codecs = codecs;
}
@CalledByNative
List<Encoding> getEncodings() {
return encodings;
}
@CalledByNative
List<Codec> getCodecs() {
return codecs;
}
} }

View File

@ -13,14 +13,14 @@ package org.webrtc;
/** Interface for observing SDP-related events. */ /** Interface for observing SDP-related events. */
public interface SdpObserver { public interface SdpObserver {
/** Called on success of Create{Offer,Answer}(). */ /** Called on success of Create{Offer,Answer}(). */
public void onCreateSuccess(SessionDescription sdp); @CalledByNative void onCreateSuccess(SessionDescription sdp);
/** Called on success of Set{Local,Remote}Description(). */ /** Called on success of Set{Local,Remote}Description(). */
public void onSetSuccess(); @CalledByNative void onSetSuccess();
/** Called on error of Create{Offer,Answer}(). */ /** Called on error of Create{Offer,Answer}(). */
public void onCreateFailure(String error); @CalledByNative void onCreateFailure(String error);
/** Called on error of Set{Local,Remote}Description(). */ /** Called on error of Set{Local,Remote}Description(). */
public void onSetFailure(String error); @CalledByNative void onSetFailure(String error);
} }

View File

@ -28,6 +28,7 @@ public class SessionDescription {
return name().toLowerCase(Locale.US); return name().toLowerCase(Locale.US);
} }
@CalledByNative("Type")
public static Type fromCanonicalForm(String canonical) { public static Type fromCanonicalForm(String canonical) {
return Type.valueOf(Type.class, canonical.toUpperCase(Locale.US)); return Type.valueOf(Type.class, canonical.toUpperCase(Locale.US));
} }
@ -36,8 +37,19 @@ public class SessionDescription {
public final Type type; public final Type type;
public final String description; public final String description;
@CalledByNative
public SessionDescription(Type type, String description) { public SessionDescription(Type type, String description) {
this.type = type; this.type = type;
this.description = description; this.description = description;
} }
@CalledByNative
String getDescription() {
return description;
}
@CalledByNative
String getTypeInCanonicalForm() {
return type.canonicalForm();
}
} }

View File

@ -234,6 +234,7 @@ public class SurfaceTextureHelper {
/** Deprecated, use textureToYuv. */ /** Deprecated, use textureToYuv. */
@Deprecated @Deprecated
@SuppressWarnings("deprecation") // yuvConverter.convert is deprecated @SuppressWarnings("deprecation") // yuvConverter.convert is deprecated
@CalledByNative
void textureToYUV(final ByteBuffer buf, final int width, final int height, final int stride, void textureToYUV(final ByteBuffer buf, final int width, final int height, final int stride,
final int textureId, final float[] transformMatrix) { final int textureId, final float[] transformMatrix) {
if (textureId != oesTextureId) { if (textureId != oesTextureId) {

View File

@ -19,9 +19,13 @@ public class TurnCustomizer {
} }
public void dispose() { public void dispose() {
nativeFreeTurnCustomizer(nativeTurnCustomizer); freeNativeTurnCustomizer(nativeTurnCustomizer);
} }
private static native void nativeFreeTurnCustomizer( private static native void freeNativeTurnCustomizer(long nativeTurnCustomizer);
long nativeTurnCustomizer);
@CalledByNative
long getNativeTurnCustomizer() {
return nativeTurnCustomizer;
}
} }

View File

@ -35,6 +35,7 @@ public class VideoCodecInfo {
public final Map<String, String> params; public final Map<String, String> params;
@Deprecated public final int payload; @Deprecated public final int payload;
@CalledByNative
public VideoCodecInfo(String name, Map<String, String> params) { public VideoCodecInfo(String name, Map<String, String> params) {
this.payload = 0; this.payload = 0;
this.name = name; this.name = name;
@ -66,4 +67,14 @@ public class VideoCodecInfo {
Object[] values = {name.toUpperCase(Locale.ROOT), params}; Object[] values = {name.toUpperCase(Locale.ROOT), params};
return Arrays.hashCode(values); return Arrays.hashCode(values);
} }
@CalledByNative
String getName() {
return name;
}
@CalledByNative
Map getParams() {
return params;
}
} }

View File

@ -16,5 +16,5 @@ public interface VideoDecoderFactory {
* Creates a VideoDecoder for the given codec. Supports the same codecs supported by * Creates a VideoDecoder for the given codec. Supports the same codecs supported by
* VideoEncoderFactory. * VideoEncoderFactory.
*/ */
public VideoDecoder createDecoder(String codecType); @CalledByNative VideoDecoder createDecoder(String codecType);
} }

View File

@ -95,7 +95,7 @@ public class VideoFrameDrawer {
// Input is packed already. // Input is packed already.
packedByteBuffer = planes[i]; packedByteBuffer = planes[i];
} else { } else {
VideoRenderer.nativeCopyPlane( VideoRenderer.copyPlaneNative(
planes[i], planeWidths[i], planeHeights[i], strides[i], copyBuffer, planeWidths[i]); planes[i], planeWidths[i], planeHeights[i], strides[i], copyBuffer, planeWidths[i]);
packedByteBuffer = copyBuffer; packedByteBuffer = copyBuffer;
} }

View File

@ -11,6 +11,7 @@
package org.webrtc; package org.webrtc;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.webrtc.VideoFrame;
/** /**
* Java version of VideoSinkInterface. In addition to allowing clients to * Java version of VideoSinkInterface. In addition to allowing clients to
@ -92,6 +93,7 @@ public class VideoRenderer {
/** /**
* Construct a frame from VideoFrame.Buffer. * Construct a frame from VideoFrame.Buffer.
*/ */
@CalledByNative("I420Frame")
public I420Frame(int rotationDegree, VideoFrame.Buffer buffer, long nativeFramePointer) { public I420Frame(int rotationDegree, VideoFrame.Buffer buffer, long nativeFramePointer) {
this.width = buffer.getWidth(); this.width = buffer.getWidth();
this.height = buffer.getHeight(); this.height = buffer.getHeight();
@ -174,10 +176,25 @@ public class VideoRenderer {
} }
return new VideoFrame(buffer, rotationDegree, 0 /* timestampNs */); return new VideoFrame(buffer, rotationDegree, 0 /* timestampNs */);
} }
@CalledByNative("I420Frame")
static I420Frame createI420Frame(int width, int height, int rotationDegree, int y_stride,
ByteBuffer y_buffer, int u_stride, ByteBuffer u_buffer, int v_stride, ByteBuffer v_buffer,
long nativeFramePointer) {
return new I420Frame(width, height, rotationDegree, new int[] {y_stride, u_stride, v_stride},
new ByteBuffer[] {y_buffer, u_buffer, v_buffer}, nativeFramePointer);
}
@CalledByNative("I420Frame")
static I420Frame createTextureFrame(int width, int height, int rotationDegree, int textureId,
float[] samplingMatrix, long nativeFramePointer) {
return new I420Frame(
width, height, rotationDegree, textureId, samplingMatrix, nativeFramePointer);
}
} }
// Helper native function to do a video frame plane copying. // Helper native function to do a video frame plane copying.
public static native void nativeCopyPlane( static native void copyPlaneNative(
ByteBuffer src, int width, int height, int srcStride, ByteBuffer dst, int dstStride); ByteBuffer src, int width, int height, int srcStride, ByteBuffer dst, int dstStride);
/** The real meat of VideoSinkInterface. */ /** The real meat of VideoSinkInterface. */
@ -186,7 +203,7 @@ public class VideoRenderer {
// should handle that by applying rotation during rendering. The callee // should handle that by applying rotation during rendering. The callee
// is responsible for signaling when it is done with |frame| by calling // is responsible for signaling when it is done with |frame| by calling
// renderFrameDone(frame). // renderFrameDone(frame).
public void renderFrame(I420Frame frame); @CalledByNative("Callbacks") void renderFrame(I420Frame frame);
} }
/** /**
@ -204,7 +221,7 @@ public class VideoRenderer {
long nativeVideoRenderer; long nativeVideoRenderer;
public VideoRenderer(Callbacks callbacks) { public VideoRenderer(Callbacks callbacks) {
nativeVideoRenderer = nativeWrapVideoRenderer(callbacks); nativeVideoRenderer = createNativeVideoRenderer(callbacks);
} }
public void dispose() { public void dispose() {
@ -217,7 +234,7 @@ public class VideoRenderer {
nativeVideoRenderer = 0; nativeVideoRenderer = 0;
} }
private static native long nativeWrapVideoRenderer(Callbacks callbacks); private static native long createNativeVideoRenderer(Callbacks callbacks);
private static native void freeWrappedVideoRenderer(long nativeVideoRenderer); private static native void freeWrappedVideoRenderer(long nativeVideoRenderer);
private static native void releaseNativeFrame(long nativeFramePointer); private static native void releaseNativeFrame(long nativeFramePointer);
} }

View File

@ -43,7 +43,7 @@ import org.junit.runner.RunWith;
* Tests for org.webrtc.NetworkMonitor. * Tests for org.webrtc.NetworkMonitor.
* *
* TODO(deadbeef): These tests don't cover the interaction between * TODO(deadbeef): These tests don't cover the interaction between
* NetworkManager.java and androidnetworkmonitor_jni.cc, which is how this * NetworkManager.java and androidnetworkmonitor.cc, which is how this
* class is used in practice in WebRTC. * class is used in practice in WebRTC.
*/ */
@SuppressLint("NewApi") @SuppressLint("NewApi")

View File

@ -638,7 +638,7 @@ public class PeerConnectionTest {
// - audit each place that uses |constraints| for specifying non-trivial // - audit each place that uses |constraints| for specifying non-trivial
// constraints (and ensure they're honored). // constraints (and ensure they're honored).
// - test error cases // - test error cases
// - ensure reasonable coverage of _jni.cc is achieved. Coverage is // - ensure reasonable coverage of jni code is achieved. Coverage is
// extra-important because of all the free-text (class/method names, etc) // extra-important because of all the free-text (class/method names, etc)
// in JNI-style programming; make sure no typos! // in JNI-style programming; make sure no typos!
// - Test that shutdown mid-interaction is crash-free. // - Test that shutdown mid-interaction is crash-free.

View File

@ -20,6 +20,7 @@ import android.opengl.EGLExt;
import android.opengl.EGLSurface; import android.opengl.EGLSurface;
import android.os.Build; import android.os.Build;
import android.view.Surface; import android.view.Surface;
import org.webrtc.EglBase;
/** /**
* Holds EGL state and utility methods for handling an EGL14 EGLContext, an EGLDisplay, * Holds EGL state and utility methods for handling an EGL14 EGLContext, an EGLDisplay,
@ -59,6 +60,11 @@ class EglBase14 implements EglBase {
public Context(android.opengl.EGLContext eglContext) { public Context(android.opengl.EGLContext eglContext) {
this.egl14Context = eglContext; this.egl14Context = eglContext;
} }
@CalledByNative("Context")
static boolean isEgl14Context(EglBase.Context context) {
return context instanceof EglBase14.Context;
}
} }
// Create a new context with the specified config type, sharing data with sharedContext. // Create a new context with the specified config type, sharing data with sharedContext.

View File

@ -45,7 +45,7 @@ class HardwareVideoEncoder implements VideoEncoder {
private static final int MAX_VIDEO_FRAMERATE = 30; private static final int MAX_VIDEO_FRAMERATE = 30;
// See MAX_ENCODER_Q_SIZE in androidmediaencoder_jni.cc. // See MAX_ENCODER_Q_SIZE in androidmediaencoder.cc.
private static final int MAX_ENCODER_Q_SIZE = 2; private static final int MAX_ENCODER_Q_SIZE = 2;
private static final int MEDIA_CODEC_RELEASE_TIMEOUT_MS = 5000; private static final int MEDIA_CODEC_RELEASE_TIMEOUT_MS = 5000;

View File

@ -0,0 +1,48 @@
/*
* 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.io.UnsupportedEncodingException;
import java.util.Map;
/**
* This class is only used from jni_helper.cc to give some Java functionality that were not possible
* to generate in other ways due to bugs.webrtc.org/8606 and bugs.webrtc.org/8632.
*/
class JniHelper {
// TODO(bugs.webrtc.org/8632): Remove.
@CalledByNative
static byte[] getStringBytes(String s) {
try {
return s.getBytes("ISO-8859-1");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("ISO-8859-1 is unsupported");
}
}
// TODO(bugs.webrtc.org/8632): Remove.
@CalledByNative
static Object getStringClass() {
return String.class;
}
// TODO(bugs.webrtc.org/8606): Remove.
@CalledByNative
static String getKey(Map.Entry<String, String> entry) {
return entry.getKey();
}
// TODO(bugs.webrtc.org/8606): Remove.
@CalledByNative
static String getValue(Map.Entry<String, String> entry) {
return entry.getValue();
}
}

View File

@ -26,6 +26,7 @@ class WrappedNativeI420Buffer implements VideoFrame.I420Buffer {
private final int strideV; private final int strideV;
private final long nativeBuffer; private final long nativeBuffer;
@CalledByNative
WrappedNativeI420Buffer(int width, int height, ByteBuffer dataY, int strideY, ByteBuffer dataU, WrappedNativeI420Buffer(int width, int height, ByteBuffer dataY, int strideY, ByteBuffer dataU,
int strideU, ByteBuffer dataV, int strideV, long nativeBuffer) { int strideU, ByteBuffer dataV, int strideV, long nativeBuffer) {
this.width = width; this.width = width;

View File

@ -1,4 +1,4 @@
per-file androidhistogram_jni.cc=sakal@webrtc.org per-file androidhistogram.cc=sakal@webrtc.org
per-file androidmetrics_jni.cc=sakal@webrtc.org per-file androidmetrics.cc=sakal@webrtc.org
per-file androidvideotracksource.*=sakal@webrtc.org per-file androidvideotracksource.*=sakal@webrtc.org
per-file androidvideotracksource_jni.cc=sakal@webrtc.org per-file androidvideotracksource.cc=sakal@webrtc.org

View File

@ -11,7 +11,6 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include "sdk/android/src/jni/classreferenceholder.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
#include "system_wrappers/include/metrics.h" #include "system_wrappers/include/metrics.h"

View File

@ -16,7 +16,6 @@
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "rtc_base/thread.h" #include "rtc_base/thread.h"
#include "sdk/android/src/jni/classreferenceholder.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
namespace webrtc { namespace webrtc {

View File

@ -29,7 +29,7 @@
#include "rtc_base/timeutils.h" #include "rtc_base/timeutils.h"
#include "sdk/android/generated_video_jni/jni/MediaCodecVideoDecoder_jni.h" #include "sdk/android/generated_video_jni/jni/MediaCodecVideoDecoder_jni.h"
#include "sdk/android/src/jni/androidmediacodeccommon.h" #include "sdk/android/src/jni/androidmediacodeccommon.h"
#include "sdk/android/src/jni/surfacetexturehelper_jni.h" #include "sdk/android/src/jni/surfacetexturehelper.h"
#include "sdk/android/src/jni/videoframe.h" #include "sdk/android/src/jni/videoframe.h"
#include "third_party/libyuv/include/libyuv/convert.h" #include "third_party/libyuv/include/libyuv/convert.h"
#include "third_party/libyuv/include/libyuv/convert_from.h" #include "third_party/libyuv/include/libyuv/convert_from.h"
@ -209,9 +209,9 @@ int32_t MediaCodecVideoDecoder::InitDecodeOnCodecThread() {
CheckOnCodecThread(); CheckOnCodecThread();
JNIEnv* jni = AttachCurrentThreadIfNeeded(); JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(jni); ScopedLocalRefFrame local_ref_frame(jni);
ALOGD << "InitDecodeOnCodecThread Type: " << (int)codecType_ << ". " ALOGD << "InitDecodeOnCodecThread Type: " << static_cast<int>(codecType_)
<< codec_.width << " x " << codec_.height << ". Fps: " << << ". " << codec_.width << " x " << codec_.height
(int)codec_.maxFramerate; << ". Fps: " << static_cast<int>(codec_.maxFramerate);
// Release previous codec first if it was allocated before. // Release previous codec first if it was allocated before.
int ret_val = ReleaseOnCodecThread(); int ret_val = ReleaseOnCodecThread();
@ -278,8 +278,8 @@ int32_t MediaCodecVideoDecoder::ResetDecodeOnCodecThread() {
CheckOnCodecThread(); CheckOnCodecThread();
JNIEnv* jni = AttachCurrentThreadIfNeeded(); JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(jni); ScopedLocalRefFrame local_ref_frame(jni);
ALOGD << "ResetDecodeOnCodecThread Type: " << (int)codecType_ << ". " ALOGD << "ResetDecodeOnCodecThread Type: " << static_cast<int>(codecType_)
<< codec_.width << " x " << codec_.height; << ". " << codec_.width << " x " << codec_.height;
ALOGD << " Frames received: " << frames_received_ << ALOGD << " Frames received: " << frames_received_ <<
". Frames decoded: " << frames_decoded_; ". Frames decoded: " << frames_decoded_;
@ -725,8 +725,8 @@ bool MediaCodecVideoDecoder::DeliverPendingOutputs(
". " << width << " x " << height << ". " << width << " x " << height <<
". Color: " << color_format << ". Color: " << color_format <<
". TS: " << presentation_timestamps_ms << ". TS: " << presentation_timestamps_ms <<
". DecTime: " << (int)decode_time_ms << ". DecTime: " << static_cast<int>(decode_time_ms) <<
". DelayTime: " << (int)frame_delayed_ms; ". DelayTime: " << static_cast<int>(frame_delayed_ms);
} }
// Calculate and print decoding statistics - every 3 seconds. // Calculate and print decoding statistics - every 3 seconds.
@ -843,18 +843,18 @@ void MediaCodecVideoDecoderFactory::SetEGLContext(
VideoDecoder* MediaCodecVideoDecoderFactory::CreateVideoDecoder( VideoDecoder* MediaCodecVideoDecoderFactory::CreateVideoDecoder(
VideoCodecType type) { VideoCodecType type) {
if (supported_codec_types_.empty()) { if (supported_codec_types_.empty()) {
ALOGW << "No HW video decoder for type " << (int)type; ALOGW << "No HW video decoder for type " << static_cast<int>(type);
return nullptr; return nullptr;
} }
for (VideoCodecType codec_type : supported_codec_types_) { for (VideoCodecType codec_type : supported_codec_types_) {
if (codec_type == type) { if (codec_type == type) {
ALOGD << "Create HW video decoder for type " << (int)type; ALOGD << "Create HW video decoder for type " << static_cast<int>(type);
JNIEnv* jni = AttachCurrentThreadIfNeeded(); JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(jni); ScopedLocalRefFrame local_ref_frame(jni);
return new MediaCodecVideoDecoder(jni, type, egl_context_); return new MediaCodecVideoDecoder(jni, type, egl_context_);
} }
} }
ALOGW << "Can not find HW video decoder for type " << (int)type; ALOGW << "Can not find HW video decoder for type " << static_cast<int>(type);
return nullptr; return nullptr;
} }

View File

@ -8,11 +8,13 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef SDK_ANDROID_SRC_JNI_ANDROIDMEDIADECODER_JNI_H_ #ifndef SDK_ANDROID_SRC_JNI_ANDROIDMEDIADECODER_H_
#define SDK_ANDROID_SRC_JNI_ANDROIDMEDIADECODER_JNI_H_ #define SDK_ANDROID_SRC_JNI_ANDROIDMEDIADECODER_H_
#include <vector>
#include "sdk/android/src/jni/jni_helpers.h"
#include "media/engine/webrtcvideodecoderfactory.h" #include "media/engine/webrtcvideodecoderfactory.h"
#include "sdk/android/src/jni/jni_helpers.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
@ -41,4 +43,4 @@ class MediaCodecVideoDecoderFactory
} // namespace jni } // namespace jni
} // namespace webrtc } // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_ANDROIDMEDIADECODER_JNI_H_ #endif // SDK_ANDROID_SRC_JNI_ANDROIDMEDIADECODER_H_

View File

@ -76,7 +76,7 @@ __android_log_print(ANDROID_LOG_VERBOSE, TAG_ENCODER, __VA_ARGS__)
#define ALOGW RTC_LOG_TAG(rtc::LS_WARNING, TAG_ENCODER) #define ALOGW RTC_LOG_TAG(rtc::LS_WARNING, TAG_ENCODER)
#define ALOGE RTC_LOG_TAG(rtc::LS_ERROR, TAG_ENCODER) #define ALOGE RTC_LOG_TAG(rtc::LS_ERROR, TAG_ENCODER)
namespace { namespace {
// Maximum time limit between incoming frames before requesting a key frame. // Maximum time limit between incoming frames before requesting a key frame.
const size_t kFrameDiffThresholdMs = 350; const size_t kFrameDiffThresholdMs = 350;
const int kMinKeyFrameInterval = 6; const int kMinKeyFrameInterval = 6;
@ -1346,7 +1346,7 @@ void MediaCodecVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
} }
JNI_FUNCTION_DECLARATION(void, JNI_FUNCTION_DECLARATION(void,
MediaCodecVideoEncoder_fillNativeBuffer, MediaCodecVideoEncoder_fillInputBufferNative,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jlong native_encoder, jlong native_encoder,

View File

@ -8,13 +8,13 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef SDK_ANDROID_SRC_JNI_ANDROIDMEDIAENCODER_JNI_H_ #ifndef SDK_ANDROID_SRC_JNI_ANDROIDMEDIAENCODER_H_
#define SDK_ANDROID_SRC_JNI_ANDROIDMEDIAENCODER_JNI_H_ #define SDK_ANDROID_SRC_JNI_ANDROIDMEDIAENCODER_H_
#include <vector> #include <vector>
#include "sdk/android/src/jni/jni_helpers.h"
#include "media/engine/webrtcvideoencoderfactory.h" #include "media/engine/webrtcvideoencoderfactory.h"
#include "sdk/android/src/jni/jni_helpers.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
@ -44,4 +44,4 @@ class MediaCodecVideoEncoderFactory
} // namespace jni } // namespace jni
} // namespace webrtc } // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_ANDROIDMEDIAENCODER_JNI_H_ #endif // SDK_ANDROID_SRC_JNI_ANDROIDMEDIAENCODER_H_

View File

@ -12,7 +12,6 @@
#include <memory> #include <memory>
#include "sdk/android/generated_metrics_jni/jni/Metrics_jni.h" #include "sdk/android/generated_metrics_jni/jni/Metrics_jni.h"
#include "sdk/android/src/jni/classreferenceholder.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
#include "system_wrappers/include/metrics.h" #include "system_wrappers/include/metrics.h"
#include "system_wrappers/include/metrics_default.h" #include "system_wrappers/include/metrics_default.h"

View File

@ -11,4 +11,4 @@
// TODO(deadbeef): Remove this file when clients are updated to new include // TODO(deadbeef): Remove this file when clients are updated to new include
// path. // path.
#include "sdk/android/src/jni/pc/androidnetworkmonitor_jni.h" #include "sdk/android/src/jni/pc/androidnetworkmonitor.h"

View File

@ -12,16 +12,28 @@
#include <utility> #include <utility>
#include "api/videosourceproxy.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "sdk/android/src/jni/classreferenceholder.h"
namespace webrtc {
namespace jni {
namespace { namespace {
// MediaCodec wants resolution to be divisible by 2. // MediaCodec wants resolution to be divisible by 2.
const int kRequiredResolutionAlignment = 2; const int kRequiredResolutionAlignment = 2;
VideoRotation jintToVideoRotation(jint rotation) {
RTC_DCHECK(rotation == 0 || rotation == 90 || rotation == 180 ||
rotation == 270);
return static_cast<VideoRotation>(rotation);
} }
namespace webrtc { AndroidVideoTrackSource* AndroidVideoTrackSourceFromJavaProxy(jlong j_proxy) {
namespace jni { auto proxy_source = reinterpret_cast<VideoTrackSourceProxy*>(j_proxy);
return reinterpret_cast<AndroidVideoTrackSource*>(proxy_source->internal());
}
} // namespace
AndroidVideoTrackSource::AndroidVideoTrackSource( AndroidVideoTrackSource::AndroidVideoTrackSource(
rtc::Thread* signaling_thread, rtc::Thread* signaling_thread,
@ -198,5 +210,99 @@ void AndroidVideoTrackSource::OnOutputFormatRequest(int width,
video_adapter()->OnOutputFormatRequest(format); video_adapter()->OnOutputFormatRequest(format);
} }
} // namespace webrtc JNI_FUNCTION_DECLARATION(
void,
AndroidVideoTrackSourceObserver_nativeOnByteBufferFrameCaptured,
JNIEnv* jni,
jclass,
jlong j_source,
jbyteArray j_frame,
jint length,
jint width,
jint height,
jint rotation,
jlong timestamp) {
AndroidVideoTrackSource* source =
AndroidVideoTrackSourceFromJavaProxy(j_source);
jbyte* bytes = jni->GetByteArrayElements(j_frame, nullptr);
source->OnByteBufferFrameCaptured(bytes, length, width, height,
jintToVideoRotation(rotation), timestamp);
jni->ReleaseByteArrayElements(j_frame, bytes, JNI_ABORT);
}
JNI_FUNCTION_DECLARATION(
void,
AndroidVideoTrackSourceObserver_nativeOnTextureFrameCaptured,
JNIEnv* jni,
jclass,
jlong j_source,
jint j_width,
jint j_height,
jint j_oes_texture_id,
jfloatArray j_transform_matrix,
jint j_rotation,
jlong j_timestamp) {
AndroidVideoTrackSource* source =
AndroidVideoTrackSourceFromJavaProxy(j_source);
source->OnTextureFrameCaptured(
j_width, j_height, jintToVideoRotation(j_rotation), j_timestamp,
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) {
AndroidVideoTrackSource* source =
AndroidVideoTrackSourceFromJavaProxy(j_source);
source->OnFrameCaptured(jni, j_width, j_height, j_timestamp_ns,
jintToVideoRotation(j_rotation),
j_video_frame_buffer);
}
JNI_FUNCTION_DECLARATION(void,
AndroidVideoTrackSourceObserver_nativeCapturerStarted,
JNIEnv* jni,
jclass,
jlong j_source,
jboolean j_success) {
RTC_LOG(LS_INFO) << "AndroidVideoTrackSourceObserve_nativeCapturerStarted";
AndroidVideoTrackSource* source =
AndroidVideoTrackSourceFromJavaProxy(j_source);
source->SetState(j_success ? AndroidVideoTrackSource::SourceState::kLive
: AndroidVideoTrackSource::SourceState::kEnded);
}
JNI_FUNCTION_DECLARATION(void,
AndroidVideoTrackSourceObserver_nativeCapturerStopped,
JNIEnv* jni,
jclass,
jlong j_source) {
RTC_LOG(LS_INFO) << "AndroidVideoTrackSourceObserve_nativeCapturerStopped";
AndroidVideoTrackSource* source =
AndroidVideoTrackSourceFromJavaProxy(j_source);
source->SetState(AndroidVideoTrackSource::SourceState::kEnded);
}
JNI_FUNCTION_DECLARATION(void,
VideoSource_nativeAdaptOutputFormat,
JNIEnv* jni,
jclass,
jlong j_source,
jint j_width,
jint j_height,
jint j_fps) {
RTC_LOG(LS_INFO) << "VideoSource_nativeAdaptOutputFormat";
AndroidVideoTrackSource* source =
AndroidVideoTrackSourceFromJavaProxy(j_source);
source->OnOutputFormatRequest(j_width, j_height, j_fps);
}
} // namespace jni
} // namespace webrtc } // namespace webrtc

View File

@ -20,7 +20,7 @@
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/thread_checker.h" #include "rtc_base/thread_checker.h"
#include "rtc_base/timestampaligner.h" #include "rtc_base/timestampaligner.h"
#include "sdk/android/src/jni/surfacetexturehelper_jni.h" #include "sdk/android/src/jni/surfacetexturehelper.h"
#include "sdk/android/src/jni/videoframe.h" #include "sdk/android/src/jni/videoframe.h"
namespace webrtc { namespace webrtc {

View File

@ -1,132 +0,0 @@
/*
* Copyright (c) 2016 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.
*/
#include "api/video/video_rotation.h"
#include "api/videosourceproxy.h"
#include "rtc_base/logging.h"
#include "sdk/android/src/jni/androidvideotracksource.h"
#include "sdk/android/src/jni/classreferenceholder.h"
namespace webrtc {
namespace {
static VideoRotation jintToVideoRotation(jint rotation) {
RTC_DCHECK(rotation == 0 || rotation == 90 || rotation == 180 ||
rotation == 270);
return static_cast<VideoRotation>(rotation);
}
} // namespace
namespace jni {
static AndroidVideoTrackSource* AndroidVideoTrackSourceFromJavaProxy(
jlong j_proxy) {
auto proxy_source = reinterpret_cast<VideoTrackSourceProxy*>(j_proxy);
return reinterpret_cast<AndroidVideoTrackSource*>(proxy_source->internal());
}
JNI_FUNCTION_DECLARATION(
void,
AndroidVideoTrackSourceObserver_nativeOnByteBufferFrameCaptured,
JNIEnv* jni,
jclass,
jlong j_source,
jbyteArray j_frame,
jint length,
jint width,
jint height,
jint rotation,
jlong timestamp) {
AndroidVideoTrackSource* source =
AndroidVideoTrackSourceFromJavaProxy(j_source);
jbyte* bytes = jni->GetByteArrayElements(j_frame, nullptr);
source->OnByteBufferFrameCaptured(bytes, length, width, height,
jintToVideoRotation(rotation), timestamp);
jni->ReleaseByteArrayElements(j_frame, bytes, JNI_ABORT);
}
JNI_FUNCTION_DECLARATION(
void,
AndroidVideoTrackSourceObserver_nativeOnTextureFrameCaptured,
JNIEnv* jni,
jclass,
jlong j_source,
jint j_width,
jint j_height,
jint j_oes_texture_id,
jfloatArray j_transform_matrix,
jint j_rotation,
jlong j_timestamp) {
AndroidVideoTrackSource* source =
AndroidVideoTrackSourceFromJavaProxy(j_source);
source->OnTextureFrameCaptured(
j_width, j_height, jintToVideoRotation(j_rotation), j_timestamp,
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) {
AndroidVideoTrackSource* source =
AndroidVideoTrackSourceFromJavaProxy(j_source);
source->OnFrameCaptured(jni, j_width, j_height, j_timestamp_ns,
jintToVideoRotation(j_rotation),
j_video_frame_buffer);
}
JNI_FUNCTION_DECLARATION(void,
AndroidVideoTrackSourceObserver_nativeCapturerStarted,
JNIEnv* jni,
jclass,
jlong j_source,
jboolean j_success) {
RTC_LOG(LS_INFO) << "AndroidVideoTrackSourceObserve_nativeCapturerStarted";
AndroidVideoTrackSource* source =
AndroidVideoTrackSourceFromJavaProxy(j_source);
source->SetState(j_success ? AndroidVideoTrackSource::SourceState::kLive
: AndroidVideoTrackSource::SourceState::kEnded);
}
JNI_FUNCTION_DECLARATION(void,
AndroidVideoTrackSourceObserver_nativeCapturerStopped,
JNIEnv* jni,
jclass,
jlong j_source) {
RTC_LOG(LS_INFO) << "AndroidVideoTrackSourceObserve_nativeCapturerStopped";
AndroidVideoTrackSource* source =
AndroidVideoTrackSourceFromJavaProxy(j_source);
source->SetState(AndroidVideoTrackSource::SourceState::kEnded);
}
JNI_FUNCTION_DECLARATION(void,
VideoSource_nativeAdaptOutputFormat,
JNIEnv* jni,
jclass,
jlong j_source,
jint j_width,
jint j_height,
jint j_fps) {
RTC_LOG(LS_INFO) << "VideoSource_nativeAdaptOutputFormat";
AndroidVideoTrackSource* source =
AndroidVideoTrackSourceFromJavaProxy(j_source);
source->OnOutputFormatRequest(j_width, j_height, j_fps);
}
} // namespace jni
} // namespace webrtc

View File

@ -1,140 +0,0 @@
/*
* Copyright 2015 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.
*/
#include "sdk/android/src/jni/classreferenceholder.h"
#include "sdk/android/src/jni/class_loader.h"
#include "sdk/android/src/jni/jni_helpers.h"
namespace webrtc {
namespace jni {
// ClassReferenceHolder holds global reference to Java classes in app/webrtc.
class ClassReferenceHolder {
public:
explicit ClassReferenceHolder(JNIEnv* jni);
~ClassReferenceHolder();
void FreeReferences(JNIEnv* jni);
jclass GetClass(const std::string& name);
private:
void LoadClass(JNIEnv* jni, const std::string& name);
std::map<std::string, jclass> classes_;
};
// Allocated in LoadGlobalClassReferenceHolder(),
// freed in FreeGlobalClassReferenceHolder().
static ClassReferenceHolder* g_class_reference_holder = nullptr;
void LoadGlobalClassReferenceHolder() {
JNIEnv* env = GetEnv();
RTC_CHECK(g_class_reference_holder == nullptr);
g_class_reference_holder = new ClassReferenceHolder(env);
// TODO(magjed): This is a weird place to call the other class loader from,
// but the only place that will keep backwards compatibility.
InitClassLoader(env);
}
void FreeGlobalClassReferenceHolder() {
g_class_reference_holder->FreeReferences(AttachCurrentThreadIfNeeded());
delete g_class_reference_holder;
g_class_reference_holder = nullptr;
}
ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) {
LoadClass(jni, "android/graphics/SurfaceTexture");
LoadClass(jni, "java/lang/String");
LoadClass(jni, "java/nio/ByteBuffer");
LoadClass(jni, "java/util/ArrayList");
LoadClass(jni, "java/util/LinkedHashMap");
LoadClass(jni, "org/webrtc/Camera1Enumerator");
LoadClass(jni, "org/webrtc/Camera2Enumerator");
LoadClass(jni, "org/webrtc/CameraEnumerationAndroid");
LoadClass(jni, "org/webrtc/EglBase");
LoadClass(jni, "org/webrtc/EglBase$Context");
LoadClass(jni, "org/webrtc/EglBase14$Context");
LoadClass(jni, "org/webrtc/EncodedImage");
LoadClass(jni, "org/webrtc/EncodedImage$FrameType");
LoadClass(jni, "org/webrtc/MediaSource$State");
LoadClass(jni, "org/webrtc/NetworkMonitor");
LoadClass(jni, "org/webrtc/NetworkMonitorAutoDetect$ConnectionType");
LoadClass(jni, "org/webrtc/NetworkMonitorAutoDetect$IPAddress");
LoadClass(jni, "org/webrtc/NetworkMonitorAutoDetect$NetworkInformation");
LoadClass(jni, "org/webrtc/PeerConnection$BundlePolicy");
LoadClass(jni, "org/webrtc/PeerConnection$CandidateNetworkPolicy");
LoadClass(jni, "org/webrtc/PeerConnection$ContinualGatheringPolicy");
LoadClass(jni, "org/webrtc/PeerConnection$IceConnectionState");
LoadClass(jni, "org/webrtc/PeerConnection$IceGatheringState");
LoadClass(jni, "org/webrtc/PeerConnection$IceTransportsType");
LoadClass(jni, "org/webrtc/PeerConnection$KeyType");
LoadClass(jni, "org/webrtc/PeerConnection$RtcpMuxPolicy");
LoadClass(jni, "org/webrtc/PeerConnection$SignalingState");
LoadClass(jni, "org/webrtc/PeerConnection$TcpCandidatePolicy");
LoadClass(jni, "org/webrtc/PeerConnection$TlsCertPolicy");
LoadClass(jni, "org/webrtc/PeerConnectionFactory");
LoadClass(jni, "org/webrtc/RTCStats");
LoadClass(jni, "org/webrtc/RTCStatsReport");
LoadClass(jni, "org/webrtc/RtpReceiver");
LoadClass(jni, "org/webrtc/RtpSender");
LoadClass(jni, "org/webrtc/SessionDescription");
LoadClass(jni, "org/webrtc/SessionDescription$Type");
LoadClass(jni, "org/webrtc/StatsReport");
LoadClass(jni, "org/webrtc/StatsReport$Value");
LoadClass(jni, "org/webrtc/SurfaceTextureHelper");
LoadClass(jni, "org/webrtc/VideoCapturer");
LoadClass(jni, "org/webrtc/VideoCodecInfo");
LoadClass(jni, "org/webrtc/VideoCodecStatus");
LoadClass(jni, "org/webrtc/VideoFrame");
LoadClass(jni, "org/webrtc/VideoFrame$Buffer");
LoadClass(jni, "org/webrtc/VideoFrame$I420Buffer");
LoadClass(jni, "org/webrtc/VideoFrame$TextureBuffer");
LoadClass(jni, "org/webrtc/VideoRenderer$I420Frame");
LoadClass(jni, "org/webrtc/VideoSink");
LoadClass(jni, "org/webrtc/WrappedNativeI420Buffer");
}
ClassReferenceHolder::~ClassReferenceHolder() {
RTC_CHECK(classes_.empty()) << "Must call FreeReferences() before dtor!";
}
void ClassReferenceHolder::FreeReferences(JNIEnv* jni) {
for (std::map<std::string, jclass>::const_iterator it = classes_.begin();
it != classes_.end(); ++it) {
jni->DeleteGlobalRef(it->second);
}
classes_.clear();
}
jclass ClassReferenceHolder::GetClass(const std::string& name) {
std::map<std::string, jclass>::iterator it = classes_.find(name);
RTC_CHECK(it != classes_.end()) << "Unexpected GetClass() call for: " << name;
return it->second;
}
void ClassReferenceHolder::LoadClass(JNIEnv* jni, const std::string& name) {
jclass localRef = jni->FindClass(name.c_str());
CHECK_EXCEPTION(jni) << "error during FindClass: " << name;
RTC_CHECK(localRef) << name;
jclass globalRef = reinterpret_cast<jclass>(jni->NewGlobalRef(localRef));
CHECK_EXCEPTION(jni) << "error during NewGlobalRef: " << name;
RTC_CHECK(globalRef) << name;
bool inserted = classes_.insert(std::make_pair(name, globalRef)).second;
RTC_CHECK(inserted) << "Duplicate class name: " << name;
}
// Returns a global reference guaranteed to be valid for the lifetime of the
// process.
jclass FindClass(JNIEnv* jni, const char* name) {
return g_class_reference_holder->GetClass(name);
}
} // namespace jni
} // namespace webrtc

View File

@ -8,35 +8,24 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
// Android's FindClass() is trickier than usual because the app-specific
// ClassLoader is not consulted when there is no app-specific frame on the
// stack. Consequently, we only look up all classes once in app/webrtc.
// http://developer.android.com/training/articles/perf-jni.html#faq_FindClass
#ifndef SDK_ANDROID_SRC_JNI_CLASSREFERENCEHOLDER_H_ #ifndef SDK_ANDROID_SRC_JNI_CLASSREFERENCEHOLDER_H_
#define SDK_ANDROID_SRC_JNI_CLASSREFERENCEHOLDER_H_ #define SDK_ANDROID_SRC_JNI_CLASSREFERENCEHOLDER_H_
// TODO(magjed): Remove this whole file and replace with either generated JNI // TODO(magjed): Update external clients to call webrtc::jni::InitClassLoader
// code or class_loader.h. // immediately instead.
#include "sdk/android/src/jni/class_loader.h"
#include <jni.h> #include "sdk/android/src/jni/jni_helpers.h"
#include <map>
#include <string>
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
// LoadGlobalClassReferenceHolder must be called in JNI_OnLoad. // Deprecated. Call webrtc::jni::InitClassLoader() immediately instead..
void LoadGlobalClassReferenceHolder(); inline void LoadGlobalClassReferenceHolder() {
// FreeGlobalClassReferenceHolder must be called in JNI_UnLoad. webrtc::jni::InitClassLoader(GetEnv());
void FreeGlobalClassReferenceHolder(); }
// Deprecated. Most cases of finding classes should be done with generated JNI // Deprecated. Do not call at all.
// code, and the few remaining cases should use the function from inline void FreeGlobalClassReferenceHolder() {}
// class_loader.h.
// Returns a global reference guaranteed to be valid for the lifetime of the
// process.
jclass FindClass(JNIEnv* jni, const char* name);
} // namespace jni } // namespace jni
} // namespace webrtc } // namespace webrtc

View File

@ -63,11 +63,13 @@ jmethodID MethodID::LazyGet(JNIEnv* env,
rtc::AtomicOps::AcquireLoadPtr(atomic_method_id); rtc::AtomicOps::AcquireLoadPtr(atomic_method_id);
if (value) if (value)
return reinterpret_cast<jmethodID>(value); return reinterpret_cast<jmethodID>(value);
jmethodID id = jmethodID id = (type == MethodID::TYPE_STATIC)
(type == MethodID::TYPE_STATIC) ? env->GetStaticMethodID(clazz, method_name, jni_signature)
? webrtc::jni::GetStaticMethodID(env, clazz, method_name, : env->GetMethodID(clazz, method_name, jni_signature);
jni_signature) CHECK_EXCEPTION(env) << "error during GetMethodID: " << method_name << ", "
: webrtc::jni::GetMethodID(env, clazz, method_name, jni_signature); << jni_signature;
RTC_CHECK(id) << method_name << ", " << jni_signature;
rtc::AtomicOps::CompareAndSwapPtr( rtc::AtomicOps::CompareAndSwapPtr(
atomic_method_id, base::subtle::AtomicWord(nullptr), atomic_method_id, base::subtle::AtomicWord(nullptr),
reinterpret_cast<base::subtle::AtomicWord>(id)); reinterpret_cast<base::subtle::AtomicWord>(id));

View File

@ -16,7 +16,9 @@
#ifndef SDK_ANDROID_SRC_JNI_JNI_GENERATOR_HELPER_H_ #ifndef SDK_ANDROID_SRC_JNI_JNI_GENERATOR_HELPER_H_
#define SDK_ANDROID_SRC_JNI_JNI_GENERATOR_HELPER_H_ #define SDK_ANDROID_SRC_JNI_JNI_GENERATOR_HELPER_H_
#include "sdk/android/src/jni/jni_helpers.h" #include <jni.h>
#include "rtc_base/checks.h"
#define CHECK_CLAZZ(env, jcaller, clazz, ...) RTC_DCHECK(clazz); #define CHECK_CLAZZ(env, jcaller, clazz, ...) RTC_DCHECK(clazz);
#define CHECK_NATIVE_PTR(env, jcaller, native_ptr, method_name, ...) \ #define CHECK_NATIVE_PTR(env, jcaller, native_ptr, method_name, ...) \
@ -26,6 +28,10 @@
#define JNI_REGISTRATION_EXPORT __attribute__((visibility("default"))) #define JNI_REGISTRATION_EXPORT __attribute__((visibility("default")))
#define JNI_GENERATOR_EXPORT extern "C" JNIEXPORT JNICALL #define JNI_GENERATOR_EXPORT extern "C" JNIEXPORT JNICALL
#define CHECK_EXCEPTION(jni) \
RTC_CHECK(!jni->ExceptionCheck()) \
<< (jni->ExceptionDescribe(), jni->ExceptionClear(), "")
namespace jni_generator { namespace jni_generator {
inline void CheckException(JNIEnv* env) { inline void CheckException(JNIEnv* env) {
CHECK_EXCEPTION(env); CHECK_EXCEPTION(env);

View File

@ -15,6 +15,7 @@
#include <unistd.h> #include <unistd.h>
#include <vector> #include <vector>
#include "sdk/android/generated_base_jni/jni/JniHelper_jni.h"
#include "sdk/android/generated_external_classes_jni/jni/ArrayList_jni.h" #include "sdk/android/generated_external_classes_jni/jni/ArrayList_jni.h"
#include "sdk/android/generated_external_classes_jni/jni/Boolean_jni.h" #include "sdk/android/generated_external_classes_jni/jni/Boolean_jni.h"
#include "sdk/android/generated_external_classes_jni/jni/Double_jni.h" #include "sdk/android/generated_external_classes_jni/jni/Double_jni.h"
@ -25,8 +26,6 @@
#include "sdk/android/generated_external_classes_jni/jni/LinkedHashMap_jni.h" #include "sdk/android/generated_external_classes_jni/jni/LinkedHashMap_jni.h"
#include "sdk/android/generated_external_classes_jni/jni/Long_jni.h" #include "sdk/android/generated_external_classes_jni/jni/Long_jni.h"
#include "sdk/android/generated_external_classes_jni/jni/Map_jni.h" #include "sdk/android/generated_external_classes_jni/jni/Map_jni.h"
#include "sdk/android/src/jni/class_loader.h"
#include "sdk/android/src/jni/classreferenceholder.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
@ -151,117 +150,21 @@ jlong jlongFromPointer(void* ptr) {
return ret; return ret;
} }
// JNIEnv-helper methods that RTC_CHECK success: no Java exception thrown and
// found object/class/method/field is non-null.
jmethodID GetMethodID(
JNIEnv* jni, jclass c, const std::string& name, const char* signature) {
jmethodID m = jni->GetMethodID(c, name.c_str(), signature);
CHECK_EXCEPTION(jni) << "error during GetMethodID: " << name << ", "
<< signature;
RTC_CHECK(m) << name << ", " << signature;
return m;
}
jmethodID GetStaticMethodID(
JNIEnv* jni, jclass c, const char* name, const char* signature) {
jmethodID m = jni->GetStaticMethodID(c, name, signature);
CHECK_EXCEPTION(jni) << "error during GetStaticMethodID: " << name << ", "
<< signature;
RTC_CHECK(m) << name << ", " << signature;
return m;
}
jfieldID GetFieldID(
JNIEnv* jni, jclass c, const char* name, const char* signature) {
jfieldID f = jni->GetFieldID(c, name, signature);
CHECK_EXCEPTION(jni) << "error during GetFieldID";
RTC_CHECK(f) << name << ", " << signature;
return f;
}
jfieldID GetStaticFieldID(JNIEnv* jni,
jclass c,
const char* name,
const char* signature) {
jfieldID f = jni->GetStaticFieldID(c, name, signature);
CHECK_EXCEPTION(jni) << "error during GetStaticFieldID";
RTC_CHECK(f) << name << ", " << signature;
return f;
}
jclass GetObjectClass(JNIEnv* jni, jobject object) {
jclass c = jni->GetObjectClass(object);
CHECK_EXCEPTION(jni) << "error during GetObjectClass";
RTC_CHECK(c) << "GetObjectClass returned NULL";
return c;
}
jobject GetObjectField(JNIEnv* jni, jobject object, jfieldID id) {
jobject o = jni->GetObjectField(object, id);
CHECK_EXCEPTION(jni) << "error during GetObjectField";
RTC_CHECK(!IsNull(jni, o)) << "GetObjectField returned NULL";
return o;
}
jobject GetStaticObjectField(JNIEnv* jni, jclass c, jfieldID id) {
jobject o = jni->GetStaticObjectField(c, id);
CHECK_EXCEPTION(jni) << "error during GetStaticObjectField";
RTC_CHECK(!IsNull(jni, o)) << "GetStaticObjectField returned NULL";
return o;
}
jobject GetNullableObjectField(JNIEnv* jni, jobject object, jfieldID id) {
jobject o = jni->GetObjectField(object, id);
CHECK_EXCEPTION(jni) << "error during GetObjectField";
return o;
}
jstring GetStringField(JNIEnv* jni, jobject object, jfieldID id) {
return static_cast<jstring>(GetObjectField(jni, object, id));
}
jlong GetLongField(JNIEnv* jni, jobject object, jfieldID id) {
jlong l = jni->GetLongField(object, id);
CHECK_EXCEPTION(jni) << "error during GetLongField";
return l;
}
jint GetIntField(JNIEnv* jni, jobject object, jfieldID id) {
jint i = jni->GetIntField(object, id);
CHECK_EXCEPTION(jni) << "error during GetIntField";
return i;
}
bool GetBooleanField(JNIEnv* jni, jobject object, jfieldID id) {
jboolean b = jni->GetBooleanField(object, id);
CHECK_EXCEPTION(jni) << "error during GetBooleanField";
return b;
}
bool IsNull(JNIEnv* jni, jobject obj) { bool IsNull(JNIEnv* jni, jobject obj) {
return jni->IsSameObject(obj, nullptr); return jni->IsSameObject(obj, nullptr);
} }
// Given a jstring, reinterprets it to a new native string. // Given a jstring, reinterprets it to a new native string.
std::string JavaToStdString(JNIEnv* jni, const jstring& j_string) { std::string JavaToStdString(JNIEnv* jni, const jstring& j_string) {
// Invoke String.getBytes(String charsetName) method to convert |j_string| const jbyteArray j_byte_array = Java_JniHelper_getStringBytes(jni, j_string);
// to a byte array.
const jclass string_class = GetObjectClass(jni, j_string);
const jmethodID get_bytes =
GetMethodID(jni, string_class, "getBytes", "(Ljava/lang/String;)[B");
const jbyteArray j_byte_array = (jbyteArray)jni->CallObjectMethod(
j_string, get_bytes, NativeToJavaString(jni, "ISO-8859-1"));
CHECK_EXCEPTION(jni) << "error during CallObjectMethod";
const size_t len = jni->GetArrayLength(j_byte_array); const size_t len = jni->GetArrayLength(j_byte_array);
CHECK_EXCEPTION(jni) << "error during GetArrayLength"; CHECK_EXCEPTION(jni) << "error during GetArrayLength";
std::vector<char> buf(len); std::string str(len, '\0');
jni->GetByteArrayRegion(j_byte_array, 0, len, jni->GetByteArrayRegion(j_byte_array, 0, len,
reinterpret_cast<jbyte*>(&buf[0])); reinterpret_cast<jbyte*>(&str[0]));
CHECK_EXCEPTION(jni) << "error during GetByteArrayRegion"; CHECK_EXCEPTION(jni) << "error during GetByteArrayRegion";
return str;
return std::string(buf.begin(), buf.end());
} }
// Given a list of jstrings, reinterprets it to a new vector of native strings. // Given a list of jstrings, reinterprets it to a new vector of native strings.
@ -282,6 +185,10 @@ rtc::Optional<int32_t> JavaToNativeOptionalInt(JNIEnv* jni, jobject integer) {
return JNI_Integer::Java_Integer_intValue(jni, integer); return JNI_Integer::Java_Integer_intValue(jni, integer);
} }
int64_t JavaToNativeLong(JNIEnv* env, jobject j_long) {
return JNI_Long::Java_Long_longValue(env, j_long);
}
jobject NativeToJavaBoolean(JNIEnv* env, bool b) { jobject NativeToJavaBoolean(JNIEnv* env, bool b) {
return JNI_Boolean::Java_Boolean_ConstructorJLB_Z(env, b); return JNI_Boolean::Java_Boolean_ConstructorJLB_Z(env, b);
} }
@ -309,29 +216,6 @@ jobject NativeToJavaInteger(JNIEnv* jni,
return optional_int ? NativeToJavaInteger(jni, *optional_int) : nullptr; return optional_int ? NativeToJavaInteger(jni, *optional_int) : nullptr;
} }
// Return the (singleton) Java Enum object corresponding to |index|;
static jobject JavaEnumFromIndex(JNIEnv* jni,
jclass state_class,
const std::string& state_class_name,
int index) {
jmethodID state_values_id = GetStaticMethodID(
jni, state_class, "values", ("()[L" + state_class_name + ";").c_str());
jobjectArray state_values = static_cast<jobjectArray>(
jni->CallStaticObjectMethod(state_class, state_values_id));
CHECK_EXCEPTION(jni) << "error during CallStaticObjectMethod";
jobject ret = jni->GetObjectArrayElement(state_values, index);
CHECK_EXCEPTION(jni) << "error during GetObjectArrayElement";
return ret;
}
jobject JavaEnumFromIndexAndClassName(JNIEnv* jni,
const std::string& state_class_fragment,
int index) {
const std::string state_class = "org/webrtc/" + state_class_fragment;
return JavaEnumFromIndex(jni, FindClass(jni, state_class.c_str()),
state_class, index);
}
std::string GetJavaEnumName(JNIEnv* jni, jobject j_enum) { std::string GetJavaEnumName(JNIEnv* jni, jobject j_enum) {
return JavaToStdString(jni, JNI_Enum::Java_Enum_name(jni, j_enum)); return JavaToStdString(jni, JNI_Enum::Java_Enum_name(jni, j_enum));
} }
@ -339,20 +223,11 @@ std::string GetJavaEnumName(JNIEnv* jni, jobject j_enum) {
std::map<std::string, std::string> JavaToStdMapStrings(JNIEnv* jni, std::map<std::string, std::string> JavaToStdMapStrings(JNIEnv* jni,
jobject j_map) { jobject j_map) {
jobject j_entry_set = JNI_Map::Java_Map_entrySet(jni, j_map); jobject j_entry_set = JNI_Map::Java_Map_entrySet(jni, j_map);
jclass entry_class = jni->FindClass("java/util/Map$Entry");
jmethodID get_key_method =
jni->GetMethodID(entry_class, "getKey", "()Ljava/lang/Object;");
jmethodID get_value_method =
jni->GetMethodID(entry_class, "getValue", "()Ljava/lang/Object;");
std::map<std::string, std::string> result; std::map<std::string, std::string> result;
for (jobject j_entry : Iterable(jni, j_entry_set)) { for (jobject j_entry : Iterable(jni, j_entry_set)) {
jstring j_key = result.insert(std::make_pair(
static_cast<jstring>(jni->CallObjectMethod(j_entry, get_key_method)); JavaToStdString(jni, Java_JniHelper_getKey(jni, j_entry)),
jstring j_value = JavaToStdString(jni, Java_JniHelper_getValue(jni, j_entry))));
static_cast<jstring>(jni->CallObjectMethod(j_entry, get_value_method));
result.insert(std::make_pair(JavaToStdString(jni, j_key),
JavaToStdString(jni, j_value)));
} }
return result; return result;
@ -468,10 +343,10 @@ jobjectArray NativeToJavaLongArray(JNIEnv* env,
jobjectArray NativeToJavaStringArray( jobjectArray NativeToJavaStringArray(
JNIEnv* env, JNIEnv* env,
const std::vector<std::string>& container) { const std::vector<std::string>& container) {
// TODO(magjed): Remove this class when we can generate it from String.class
// directly (the script currently chokes on that class).
return NativeToJavaObjectArray( return NativeToJavaObjectArray(
env, container, FindClass(env, "java/lang/String"), &NativeToJavaString); env, container,
static_cast<jclass>(Java_JniHelper_getStringClass(env).obj()),
&NativeToJavaString);
} }
JavaMapBuilder::JavaMapBuilder(JNIEnv* env) JavaMapBuilder::JavaMapBuilder(JNIEnv* env)

View File

@ -33,12 +33,6 @@
RTC_CHECK(!jni->ExceptionCheck()) \ RTC_CHECK(!jni->ExceptionCheck()) \
<< (jni->ExceptionDescribe(), jni->ExceptionClear(), "") << (jni->ExceptionDescribe(), jni->ExceptionClear(), "")
// Helper that calls ptr->Release() and aborts the process with a useful
// message if that didn't actually delete *ptr because of extra refcounts.
#define CHECK_RELEASE(ptr) \
RTC_CHECK((ptr)->Release() == rtc::RefCountReleaseStatus::kDroppedLastRef) \
<< "Unexpected refcount."
// Convenience macro defining JNI-accessible methods in the org.webrtc package. // Convenience macro defining JNI-accessible methods in the org.webrtc package.
// Eliminates unnecessary boilerplate and line-wraps, reducing visual clutter. // Eliminates unnecessary boilerplate and line-wraps, reducing visual clutter.
#define JNI_FUNCTION_DECLARATION(rettype, name, ...) \ #define JNI_FUNCTION_DECLARATION(rettype, name, ...) \
@ -62,39 +56,6 @@ JNIEnv* AttachCurrentThreadIfNeeded();
// function expecting a 64-bit param) picks up garbage in the high 32 bits. // function expecting a 64-bit param) picks up garbage in the high 32 bits.
jlong jlongFromPointer(void* ptr); jlong jlongFromPointer(void* ptr);
// JNIEnv-helper methods that RTC_CHECK success: no Java exception thrown and
// found object/class/method/field is non-null.
jmethodID GetMethodID(
JNIEnv* jni, jclass c, const std::string& name, const char* signature);
jmethodID GetStaticMethodID(
JNIEnv* jni, jclass c, const char* name, const char* signature);
jfieldID GetFieldID(JNIEnv* jni, jclass c, const char* name,
const char* signature);
jfieldID GetStaticFieldID(JNIEnv* jni,
jclass c,
const char* name,
const char* signature);
jclass GetObjectClass(JNIEnv* jni, jobject object);
// Throws an exception if the object field is null.
jobject GetObjectField(JNIEnv* jni, jobject object, jfieldID id);
jobject GetStaticObjectField(JNIEnv* jni, jclass c, jfieldID id);
jobject GetNullableObjectField(JNIEnv* jni, jobject object, jfieldID id);
jstring GetStringField(JNIEnv* jni, jobject object, jfieldID id);
jlong GetLongField(JNIEnv* jni, jobject object, jfieldID id);
jint GetIntField(JNIEnv* jni, jobject object, jfieldID id);
bool GetBooleanField(JNIEnv* jni, jobject object, jfieldID id);
// Returns true if |obj| == null in Java. // Returns true if |obj| == null in Java.
bool IsNull(JNIEnv* jni, jobject obj); bool IsNull(JNIEnv* jni, jobject obj);
@ -106,6 +67,7 @@ std::string JavaToStdString(JNIEnv* jni, const jstring& j_string);
std::vector<std::string> JavaToStdVectorStrings(JNIEnv* jni, jobject list); std::vector<std::string> JavaToStdVectorStrings(JNIEnv* jni, jobject list);
rtc::Optional<int32_t> JavaToNativeOptionalInt(JNIEnv* jni, jobject integer); rtc::Optional<int32_t> JavaToNativeOptionalInt(JNIEnv* jni, jobject integer);
int64_t JavaToNativeLong(JNIEnv* env, jobject j_long);
jobject NativeToJavaBoolean(JNIEnv* env, bool b); jobject NativeToJavaBoolean(JNIEnv* env, bool b);
jobject NativeToJavaInteger(JNIEnv* jni, int32_t i); jobject NativeToJavaInteger(JNIEnv* jni, int32_t i);
@ -116,12 +78,6 @@ jstring NativeToJavaString(JNIEnv* jni, const std::string& native);
jobject NativeToJavaInteger(JNIEnv* jni, jobject NativeToJavaInteger(JNIEnv* jni,
const rtc::Optional<int32_t>& optional_int); const rtc::Optional<int32_t>& optional_int);
// Return the (singleton) Java Enum object corresponding to |index|;
// |state_class_fragment| is something like "MediaSource$State".
jobject JavaEnumFromIndexAndClassName(JNIEnv* jni,
const std::string& state_class_fragment,
int index);
// Parses Map<String, String> to std::map<std::string, std::string>. // Parses Map<String, String> to std::map<std::string, std::string>.
std::map<std::string, std::string> JavaToStdMapStrings(JNIEnv* jni, std::map<std::string, std::string> JavaToStdMapStrings(JNIEnv* jni,
jobject j_map); jobject j_map);

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "sdk/android/src/jni/pc/androidnetworkmonitor_jni.h" #include "sdk/android/src/jni/pc/androidnetworkmonitor.h"
#include <dlfcn.h> #include <dlfcn.h>
// This was added in Lollipop to dlfcn.h // This was added in Lollipop to dlfcn.h

View File

@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef SDK_ANDROID_SRC_JNI_PC_ANDROIDNETWORKMONITOR_JNI_H_ #ifndef SDK_ANDROID_SRC_JNI_PC_ANDROIDNETWORKMONITOR_H_
#define SDK_ANDROID_SRC_JNI_PC_ANDROIDNETWORKMONITOR_JNI_H_ #define SDK_ANDROID_SRC_JNI_PC_ANDROIDNETWORKMONITOR_H_
#include <stdint.h> #include <stdint.h>
#include <map> #include <map>
@ -111,4 +111,4 @@ using webrtc::jni::AndroidNetworkMonitorFactory;
} // namespace webrtc_jni } // namespace webrtc_jni
#endif // SDK_ANDROID_SRC_JNI_PC_ANDROIDNETWORKMONITOR_JNI_H_ #endif // SDK_ANDROID_SRC_JNI_PC_ANDROIDNETWORKMONITOR_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "sdk/android/src/jni/pc/audio_jni.h" #include "sdk/android/src/jni/pc/audio.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h" #include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h" #include "api/audio_codecs/builtin_audio_encoder_factory.h"

View File

@ -8,13 +8,13 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef SDK_ANDROID_SRC_JNI_PC_AUDIO_JNI_H_ #ifndef SDK_ANDROID_SRC_JNI_PC_AUDIO_H_
#define SDK_ANDROID_SRC_JNI_PC_AUDIO_JNI_H_ #define SDK_ANDROID_SRC_JNI_PC_AUDIO_H_
// Adding 'nogncheck' to disable the gn include headers check. // Adding 'nogncheck' to disable the gn include headers check.
// We don't want this target depend on audio related targets // We don't want this target depend on audio related targets
#include "api/audio_codecs/audio_decoder_factory.h" // nogncheck #include "api/audio_codecs/audio_decoder_factory.h" // nogncheck
#include "api/audio_codecs/audio_encoder_factory.h" // nogncheck #include "api/audio_codecs/audio_encoder_factory.h" // nogncheck
#include "modules/audio_processing/include/audio_processing.h" // nogncheck #include "modules/audio_processing/include/audio_processing.h" // nogncheck
#include "rtc_base/scoped_ref_ptr.h" #include "rtc_base/scoped_ref_ptr.h"
@ -30,4 +30,4 @@ rtc::scoped_refptr<AudioProcessing> CreateAudioProcessing();
} // namespace jni } // namespace jni
} // namespace webrtc } // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_PC_AUDIO_JNI_H_ #endif // SDK_ANDROID_SRC_JNI_PC_AUDIO_H_

View File

@ -0,0 +1,202 @@
/*
* 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.
*/
#include "sdk/android/src/jni/pc/icecandidate.h"
#include <string>
#include "pc/webrtcsdp.h"
#include "sdk/android/generated_peerconnection_jni/jni/IceCandidate_jni.h"
#include "sdk/android/src/jni/pc/mediastreamtrack.h"
namespace webrtc {
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) {
return Java_IceCandidate_Constructor(
env, NativeToJavaString(env, sdp_mid), sdp_mline_index,
NativeToJavaString(env, sdp), NativeToJavaString(env, server_url));
}
} // namespace
cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, jobject j_candidate) {
std::string sdp_mid =
JavaToStdString(jni, Java_IceCandidate_getSdpMid(jni, j_candidate));
std::string sdp =
JavaToStdString(jni, Java_IceCandidate_getSdp(jni, j_candidate));
cricket::Candidate candidate;
if (!SdpDeserializeCandidate(sdp_mid, sdp, &candidate, NULL)) {
RTC_LOG(LS_ERROR) << "SdpDescrializeCandidate failed with sdp " << sdp;
}
return candidate;
}
jobject NativeToJavaCandidate(JNIEnv* env,
const cricket::Candidate& candidate) {
std::string sdp = SdpSerializeCandidate(candidate);
RTC_CHECK(!sdp.empty()) << "got an empty ICE candidate";
// sdp_mline_index is not used, pass an invalid value -1.
return CreateJavaIceCandidate(env, candidate.transport_name(),
-1 /* sdp_mline_index */, sdp,
"" /* server_url */);
}
jobject NativeToJavaIceCandidate(JNIEnv* env,
const IceCandidateInterface& candidate) {
std::string sdp;
RTC_CHECK(candidate.ToString(&sdp)) << "got so far: " << sdp;
return CreateJavaIceCandidate(env, candidate.sdp_mid(),
candidate.sdp_mline_index(), sdp,
candidate.candidate().url());
}
jobjectArray NativeToJavaCandidateArray(
JNIEnv* jni,
const std::vector<cricket::Candidate>& candidates) {
return NativeToJavaObjectArray(jni, candidates,
org_webrtc_IceCandidate_clazz(jni),
&NativeToJavaCandidate);
}
PeerConnectionInterface::IceTransportsType JavaToNativeIceTransportsType(
JNIEnv* jni,
jobject j_ice_transports_type) {
std::string enum_name = GetJavaEnumName(jni, j_ice_transports_type);
if (enum_name == "ALL")
return PeerConnectionInterface::kAll;
if (enum_name == "RELAY")
return PeerConnectionInterface::kRelay;
if (enum_name == "NOHOST")
return PeerConnectionInterface::kNoHost;
if (enum_name == "NONE")
return PeerConnectionInterface::kNone;
RTC_CHECK(false) << "Unexpected IceTransportsType enum_name " << enum_name;
return PeerConnectionInterface::kAll;
}
PeerConnectionInterface::BundlePolicy JavaToNativeBundlePolicy(
JNIEnv* jni,
jobject j_bundle_policy) {
std::string enum_name = GetJavaEnumName(jni, j_bundle_policy);
if (enum_name == "BALANCED")
return PeerConnectionInterface::kBundlePolicyBalanced;
if (enum_name == "MAXBUNDLE")
return PeerConnectionInterface::kBundlePolicyMaxBundle;
if (enum_name == "MAXCOMPAT")
return PeerConnectionInterface::kBundlePolicyMaxCompat;
RTC_CHECK(false) << "Unexpected BundlePolicy enum_name " << enum_name;
return PeerConnectionInterface::kBundlePolicyBalanced;
}
PeerConnectionInterface::RtcpMuxPolicy JavaToNativeRtcpMuxPolicy(
JNIEnv* jni,
jobject j_rtcp_mux_policy) {
std::string enum_name = GetJavaEnumName(jni, j_rtcp_mux_policy);
if (enum_name == "NEGOTIATE")
return PeerConnectionInterface::kRtcpMuxPolicyNegotiate;
if (enum_name == "REQUIRE")
return PeerConnectionInterface::kRtcpMuxPolicyRequire;
RTC_CHECK(false) << "Unexpected RtcpMuxPolicy enum_name " << enum_name;
return PeerConnectionInterface::kRtcpMuxPolicyNegotiate;
}
PeerConnectionInterface::TcpCandidatePolicy JavaToNativeTcpCandidatePolicy(
JNIEnv* jni,
jobject j_tcp_candidate_policy) {
std::string enum_name = GetJavaEnumName(jni, j_tcp_candidate_policy);
if (enum_name == "ENABLED")
return PeerConnectionInterface::kTcpCandidatePolicyEnabled;
if (enum_name == "DISABLED")
return PeerConnectionInterface::kTcpCandidatePolicyDisabled;
RTC_CHECK(false) << "Unexpected TcpCandidatePolicy enum_name " << enum_name;
return PeerConnectionInterface::kTcpCandidatePolicyEnabled;
}
PeerConnectionInterface::CandidateNetworkPolicy
JavaToNativeCandidateNetworkPolicy(JNIEnv* jni,
jobject j_candidate_network_policy) {
std::string enum_name = GetJavaEnumName(jni, j_candidate_network_policy);
if (enum_name == "ALL")
return PeerConnectionInterface::kCandidateNetworkPolicyAll;
if (enum_name == "LOW_COST")
return PeerConnectionInterface::kCandidateNetworkPolicyLowCost;
RTC_CHECK(false) << "Unexpected CandidateNetworkPolicy enum_name "
<< enum_name;
return PeerConnectionInterface::kCandidateNetworkPolicyAll;
}
rtc::KeyType JavaToNativeKeyType(JNIEnv* jni, jobject j_key_type) {
std::string enum_name = GetJavaEnumName(jni, j_key_type);
if (enum_name == "RSA")
return rtc::KT_RSA;
if (enum_name == "ECDSA")
return rtc::KT_ECDSA;
RTC_CHECK(false) << "Unexpected KeyType enum_name " << enum_name;
return rtc::KT_ECDSA;
}
PeerConnectionInterface::ContinualGatheringPolicy
JavaToNativeContinualGatheringPolicy(JNIEnv* jni, jobject j_gathering_policy) {
std::string enum_name = GetJavaEnumName(jni, j_gathering_policy);
if (enum_name == "GATHER_ONCE")
return PeerConnectionInterface::GATHER_ONCE;
if (enum_name == "GATHER_CONTINUALLY")
return PeerConnectionInterface::GATHER_CONTINUALLY;
RTC_CHECK(false) << "Unexpected ContinualGatheringPolicy enum name "
<< enum_name;
return PeerConnectionInterface::GATHER_ONCE;
}
PeerConnectionInterface::TlsCertPolicy JavaToNativeTlsCertPolicy(
JNIEnv* jni,
jobject j_ice_server_tls_cert_policy) {
std::string enum_name = GetJavaEnumName(jni, j_ice_server_tls_cert_policy);
if (enum_name == "TLS_CERT_POLICY_SECURE")
return PeerConnectionInterface::kTlsCertPolicySecure;
if (enum_name == "TLS_CERT_POLICY_INSECURE_NO_CHECK")
return PeerConnectionInterface::kTlsCertPolicyInsecureNoCheck;
RTC_CHECK(false) << "Unexpected TlsCertPolicy enum_name " << enum_name;
return PeerConnectionInterface::kTlsCertPolicySecure;
}
} // namespace jni
} // namespace webrtc

View File

@ -8,32 +8,22 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef SDK_ANDROID_SRC_JNI_PC_JAVA_NATIVE_CONVERSION_H_ #ifndef SDK_ANDROID_SRC_JNI_PC_ICECANDIDATE_H_
#define SDK_ANDROID_SRC_JNI_PC_JAVA_NATIVE_CONVERSION_H_ #define SDK_ANDROID_SRC_JNI_PC_ICECANDIDATE_H_
#include <vector> #include <vector>
#include "api/datachannelinterface.h" #include "api/datachannelinterface.h"
#include "api/jsep.h" #include "api/jsep.h"
#include "api/jsepicecandidate.h" #include "api/jsepicecandidate.h"
#include "api/mediastreaminterface.h"
#include "api/mediatypes.h"
#include "api/peerconnectioninterface.h" #include "api/peerconnectioninterface.h"
#include "api/rtpparameters.h" #include "api/rtpparameters.h"
#include "rtc_base/sslidentity.h" #include "rtc_base/sslidentity.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
// This file contains helper methods for converting between simple C++ and Java
// PeerConnection-related structures. Similar to some methods in jni_helpers.h,
// but specifically for structures tied to the PeerConnection API.
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
cricket::MediaType JavaToNativeMediaType(JNIEnv* jni, jobject j_media_type);
jobject NativeToJavaMediaType(JNIEnv* jni, cricket::MediaType media_type);
cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, jobject j_candidate); cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, jobject j_candidate);
jobject NativeToJavaCandidate(JNIEnv* env, const cricket::Candidate& candidate); jobject NativeToJavaCandidate(JNIEnv* env, const cricket::Candidate& candidate);
@ -45,16 +35,6 @@ jobjectArray NativeToJavaCandidateArray(
JNIEnv* jni, JNIEnv* jni,
const std::vector<cricket::Candidate>& candidates); const std::vector<cricket::Candidate>& candidates);
std::unique_ptr<SessionDescriptionInterface> JavaToNativeSessionDescription(
JNIEnv* jni,
jobject j_sdp);
jobject NativeToJavaSessionDescription(JNIEnv* jni,
const SessionDescriptionInterface* desc);
PeerConnectionFactoryInterface::Options
JavaToNativePeerConnectionFactoryOptions(JNIEnv* jni, jobject options);
/***************************************************** /*****************************************************
* Below are all things that go into RTCConfiguration. * Below are all things that go into RTCConfiguration.
*****************************************************/ *****************************************************/
@ -87,14 +67,7 @@ PeerConnectionInterface::TlsCertPolicy JavaToNativeTlsCertPolicy(
JNIEnv* jni, JNIEnv* jni,
jobject j_ice_server_tls_cert_policy); jobject j_ice_server_tls_cert_policy);
/*********************************************************
* RtpParameters, used for RtpSender and RtpReceiver APIs.
*********************************************************/
RtpParameters JavaToNativeRtpParameters(JNIEnv* jni, jobject j_parameters);
jobject NativeToJavaRtpParameters(JNIEnv* jni, const RtpParameters& parameters);
} // namespace jni } // namespace jni
} // namespace webrtc } // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_PC_JAVA_NATIVE_CONVERSION_H_ #endif // SDK_ANDROID_SRC_JNI_PC_ICECANDIDATE_H_

View File

@ -1,443 +0,0 @@
/*
* 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.
*/
#include "sdk/android/src/jni/pc/java_native_conversion.h"
#include <string>
#include "pc/webrtcsdp.h"
#include "sdk/android/generated_peerconnection_jni/jni/IceCandidate_jni.h"
#include "sdk/android/generated_peerconnection_jni/jni/MediaStreamTrack_jni.h"
#include "sdk/android/src/jni/classreferenceholder.h"
namespace webrtc {
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) {
return Java_IceCandidate_Constructor(
env, NativeToJavaString(env, sdp_mid), sdp_mline_index,
NativeToJavaString(env, sdp), NativeToJavaString(env, server_url));
}
} // namespace
jobject NativeToJavaMediaType(JNIEnv* jni, cricket::MediaType media_type) {
return Java_MediaType_fromNativeIndex(jni, media_type);
}
cricket::MediaType JavaToNativeMediaType(JNIEnv* jni, jobject j_media_type) {
return static_cast<cricket::MediaType>(
Java_MediaType_getNative(jni, j_media_type));
}
cricket::Candidate JavaToNativeCandidate(JNIEnv* jni, jobject j_candidate) {
std::string sdp_mid =
JavaToStdString(jni, Java_IceCandidate_getSdpMid(jni, j_candidate));
std::string sdp =
JavaToStdString(jni, Java_IceCandidate_getSdp(jni, j_candidate));
cricket::Candidate candidate;
if (!SdpDeserializeCandidate(sdp_mid, sdp, &candidate, NULL)) {
RTC_LOG(LS_ERROR) << "SdpDescrializeCandidate failed with sdp " << sdp;
}
return candidate;
}
jobject NativeToJavaCandidate(JNIEnv* env,
const cricket::Candidate& candidate) {
std::string sdp = SdpSerializeCandidate(candidate);
RTC_CHECK(!sdp.empty()) << "got an empty ICE candidate";
// sdp_mline_index is not used, pass an invalid value -1.
return CreateJavaIceCandidate(env, candidate.transport_name(),
-1 /* sdp_mline_index */, sdp,
"" /* server_url */);
}
jobject NativeToJavaIceCandidate(JNIEnv* env,
const IceCandidateInterface& candidate) {
std::string sdp;
RTC_CHECK(candidate.ToString(&sdp)) << "got so far: " << sdp;
return CreateJavaIceCandidate(env, candidate.sdp_mid(),
candidate.sdp_mline_index(), sdp,
candidate.candidate().url());
}
jobjectArray NativeToJavaCandidateArray(
JNIEnv* jni,
const std::vector<cricket::Candidate>& candidates) {
return NativeToJavaObjectArray(jni, candidates,
org_webrtc_IceCandidate_clazz(jni),
&NativeToJavaCandidate);
}
std::unique_ptr<SessionDescriptionInterface> JavaToNativeSessionDescription(
JNIEnv* jni,
jobject j_sdp) {
jfieldID j_type_id = GetFieldID(jni, GetObjectClass(jni, j_sdp), "type",
"Lorg/webrtc/SessionDescription$Type;");
jobject j_type = GetObjectField(jni, j_sdp, j_type_id);
jmethodID j_canonical_form_id =
GetMethodID(jni, GetObjectClass(jni, j_type), "canonicalForm",
"()Ljava/lang/String;");
jstring j_type_string =
(jstring)jni->CallObjectMethod(j_type, j_canonical_form_id);
CHECK_EXCEPTION(jni) << "error during CallObjectMethod";
std::string std_type = JavaToStdString(jni, j_type_string);
rtc::Optional<SdpType> sdp_type_maybe = SdpTypeFromString(std_type);
if (!sdp_type_maybe) {
RTC_LOG(LS_ERROR) << "Unexpected SDP type: " << std_type;
return nullptr;
}
jfieldID j_description_id = GetFieldID(jni, GetObjectClass(jni, j_sdp),
"description", "Ljava/lang/String;");
jstring j_description = (jstring)GetObjectField(jni, j_sdp, j_description_id);
std::string std_description = JavaToStdString(jni, j_description);
return CreateSessionDescription(*sdp_type_maybe, std_description);
}
jobject NativeToJavaSessionDescription(
JNIEnv* jni,
const SessionDescriptionInterface* desc) {
std::string sdp;
RTC_CHECK(desc->ToString(&sdp)) << "got so far: " << sdp;
jstring j_description = NativeToJavaString(jni, sdp);
jclass j_type_class = FindClass(jni, "org/webrtc/SessionDescription$Type");
jmethodID j_type_from_canonical = GetStaticMethodID(
jni, j_type_class, "fromCanonicalForm",
"(Ljava/lang/String;)Lorg/webrtc/SessionDescription$Type;");
jstring j_type_string = NativeToJavaString(jni, desc->type());
jobject j_type = jni->CallStaticObjectMethod(
j_type_class, j_type_from_canonical, j_type_string);
CHECK_EXCEPTION(jni) << "error during CallObjectMethod";
jclass j_sdp_class = FindClass(jni, "org/webrtc/SessionDescription");
jmethodID j_sdp_ctor =
GetMethodID(jni, j_sdp_class, "<init>",
"(Lorg/webrtc/SessionDescription$Type;Ljava/lang/String;)V");
jobject j_sdp =
jni->NewObject(j_sdp_class, j_sdp_ctor, j_type, j_description);
CHECK_EXCEPTION(jni) << "error during NewObject";
return j_sdp;
}
PeerConnectionFactoryInterface::Options
JavaToNativePeerConnectionFactoryOptions(JNIEnv* jni, jobject options) {
jclass options_class = jni->GetObjectClass(options);
jfieldID network_ignore_mask_field =
jni->GetFieldID(options_class, "networkIgnoreMask", "I");
int network_ignore_mask =
jni->GetIntField(options, network_ignore_mask_field);
jfieldID disable_encryption_field =
jni->GetFieldID(options_class, "disableEncryption", "Z");
bool disable_encryption =
jni->GetBooleanField(options, disable_encryption_field);
jfieldID disable_network_monitor_field =
jni->GetFieldID(options_class, "disableNetworkMonitor", "Z");
bool disable_network_monitor =
jni->GetBooleanField(options, disable_network_monitor_field);
PeerConnectionFactoryInterface::Options native_options;
// This doesn't necessarily match the c++ version of this struct; feel free
// to add more parameters as necessary.
native_options.network_ignore_mask = network_ignore_mask;
native_options.disable_encryption = disable_encryption;
native_options.disable_network_monitor = disable_network_monitor;
return native_options;
}
PeerConnectionInterface::IceTransportsType JavaToNativeIceTransportsType(
JNIEnv* jni,
jobject j_ice_transports_type) {
std::string enum_name = GetJavaEnumName(jni, j_ice_transports_type);
if (enum_name == "ALL")
return PeerConnectionInterface::kAll;
if (enum_name == "RELAY")
return PeerConnectionInterface::kRelay;
if (enum_name == "NOHOST")
return PeerConnectionInterface::kNoHost;
if (enum_name == "NONE")
return PeerConnectionInterface::kNone;
RTC_CHECK(false) << "Unexpected IceTransportsType enum_name " << enum_name;
return PeerConnectionInterface::kAll;
}
PeerConnectionInterface::BundlePolicy JavaToNativeBundlePolicy(
JNIEnv* jni,
jobject j_bundle_policy) {
std::string enum_name = GetJavaEnumName(jni, j_bundle_policy);
if (enum_name == "BALANCED")
return PeerConnectionInterface::kBundlePolicyBalanced;
if (enum_name == "MAXBUNDLE")
return PeerConnectionInterface::kBundlePolicyMaxBundle;
if (enum_name == "MAXCOMPAT")
return PeerConnectionInterface::kBundlePolicyMaxCompat;
RTC_CHECK(false) << "Unexpected BundlePolicy enum_name " << enum_name;
return PeerConnectionInterface::kBundlePolicyBalanced;
}
PeerConnectionInterface::RtcpMuxPolicy JavaToNativeRtcpMuxPolicy(
JNIEnv* jni,
jobject j_rtcp_mux_policy) {
std::string enum_name = GetJavaEnumName(jni, j_rtcp_mux_policy);
if (enum_name == "NEGOTIATE")
return PeerConnectionInterface::kRtcpMuxPolicyNegotiate;
if (enum_name == "REQUIRE")
return PeerConnectionInterface::kRtcpMuxPolicyRequire;
RTC_CHECK(false) << "Unexpected RtcpMuxPolicy enum_name " << enum_name;
return PeerConnectionInterface::kRtcpMuxPolicyNegotiate;
}
PeerConnectionInterface::TcpCandidatePolicy JavaToNativeTcpCandidatePolicy(
JNIEnv* jni,
jobject j_tcp_candidate_policy) {
std::string enum_name = GetJavaEnumName(jni, j_tcp_candidate_policy);
if (enum_name == "ENABLED")
return PeerConnectionInterface::kTcpCandidatePolicyEnabled;
if (enum_name == "DISABLED")
return PeerConnectionInterface::kTcpCandidatePolicyDisabled;
RTC_CHECK(false) << "Unexpected TcpCandidatePolicy enum_name " << enum_name;
return PeerConnectionInterface::kTcpCandidatePolicyEnabled;
}
PeerConnectionInterface::CandidateNetworkPolicy
JavaToNativeCandidateNetworkPolicy(JNIEnv* jni,
jobject j_candidate_network_policy) {
std::string enum_name = GetJavaEnumName(jni, j_candidate_network_policy);
if (enum_name == "ALL")
return PeerConnectionInterface::kCandidateNetworkPolicyAll;
if (enum_name == "LOW_COST")
return PeerConnectionInterface::kCandidateNetworkPolicyLowCost;
RTC_CHECK(false) << "Unexpected CandidateNetworkPolicy enum_name "
<< enum_name;
return PeerConnectionInterface::kCandidateNetworkPolicyAll;
}
rtc::KeyType JavaToNativeKeyType(JNIEnv* jni, jobject j_key_type) {
std::string enum_name = GetJavaEnumName(jni, j_key_type);
if (enum_name == "RSA")
return rtc::KT_RSA;
if (enum_name == "ECDSA")
return rtc::KT_ECDSA;
RTC_CHECK(false) << "Unexpected KeyType enum_name " << enum_name;
return rtc::KT_ECDSA;
}
PeerConnectionInterface::ContinualGatheringPolicy
JavaToNativeContinualGatheringPolicy(JNIEnv* jni, jobject j_gathering_policy) {
std::string enum_name = GetJavaEnumName(jni, j_gathering_policy);
if (enum_name == "GATHER_ONCE")
return PeerConnectionInterface::GATHER_ONCE;
if (enum_name == "GATHER_CONTINUALLY")
return PeerConnectionInterface::GATHER_CONTINUALLY;
RTC_CHECK(false) << "Unexpected ContinualGatheringPolicy enum name "
<< enum_name;
return PeerConnectionInterface::GATHER_ONCE;
}
PeerConnectionInterface::TlsCertPolicy JavaToNativeTlsCertPolicy(
JNIEnv* jni,
jobject j_ice_server_tls_cert_policy) {
std::string enum_name = GetJavaEnumName(jni, j_ice_server_tls_cert_policy);
if (enum_name == "TLS_CERT_POLICY_SECURE")
return PeerConnectionInterface::kTlsCertPolicySecure;
if (enum_name == "TLS_CERT_POLICY_INSECURE_NO_CHECK")
return PeerConnectionInterface::kTlsCertPolicyInsecureNoCheck;
RTC_CHECK(false) << "Unexpected TlsCertPolicy enum_name " << enum_name;
return PeerConnectionInterface::kTlsCertPolicySecure;
}
RtpParameters JavaToNativeRtpParameters(JNIEnv* jni, jobject j_parameters) {
RtpParameters parameters;
jclass parameters_class = jni->FindClass("org/webrtc/RtpParameters");
jfieldID encodings_id =
GetFieldID(jni, parameters_class, "encodings", "Ljava/util/List;");
jfieldID codecs_id =
GetFieldID(jni, parameters_class, "codecs", "Ljava/util/List;");
// Convert encodings.
jobject j_encodings = GetObjectField(jni, j_parameters, encodings_id);
jclass j_encoding_parameters_class =
jni->FindClass("org/webrtc/RtpParameters$Encoding");
jfieldID active_id =
GetFieldID(jni, j_encoding_parameters_class, "active", "Z");
jfieldID bitrate_id = GetFieldID(jni, j_encoding_parameters_class,
"maxBitrateBps", "Ljava/lang/Integer;");
jfieldID ssrc_id =
GetFieldID(jni, j_encoding_parameters_class, "ssrc", "Ljava/lang/Long;");
jclass j_long_class = jni->FindClass("java/lang/Long");
jmethodID long_value_id = GetMethodID(jni, j_long_class, "longValue", "()J");
for (jobject j_encoding_parameters : Iterable(jni, j_encodings)) {
RtpEncodingParameters encoding;
encoding.active = GetBooleanField(jni, j_encoding_parameters, active_id);
jobject j_bitrate =
GetNullableObjectField(jni, j_encoding_parameters, bitrate_id);
encoding.max_bitrate_bps = JavaToNativeOptionalInt(jni, j_bitrate);
jobject j_ssrc =
GetNullableObjectField(jni, j_encoding_parameters, ssrc_id);
if (!IsNull(jni, j_ssrc)) {
jlong ssrc_value = jni->CallLongMethod(j_ssrc, long_value_id);
CHECK_EXCEPTION(jni) << "error during CallLongMethod";
encoding.ssrc = ssrc_value;
}
parameters.encodings.push_back(encoding);
}
// Convert codecs.
jobject j_codecs = GetObjectField(jni, j_parameters, codecs_id);
jclass codec_class = jni->FindClass("org/webrtc/RtpParameters$Codec");
jfieldID payload_type_id = GetFieldID(jni, codec_class, "payloadType", "I");
jfieldID name_id = GetFieldID(jni, codec_class, "name", "Ljava/lang/String;");
jfieldID kind_id = GetFieldID(jni, codec_class, "kind",
"Lorg/webrtc/MediaStreamTrack$MediaType;");
jfieldID clock_rate_id =
GetFieldID(jni, codec_class, "clockRate", "Ljava/lang/Integer;");
jfieldID num_channels_id =
GetFieldID(jni, codec_class, "numChannels", "Ljava/lang/Integer;");
for (jobject j_codec : Iterable(jni, j_codecs)) {
RtpCodecParameters codec;
codec.payload_type = GetIntField(jni, j_codec, payload_type_id);
codec.name = JavaToStdString(jni, GetStringField(jni, j_codec, name_id));
codec.kind =
JavaToNativeMediaType(jni, GetObjectField(jni, j_codec, kind_id));
jobject j_clock_rate = GetNullableObjectField(jni, j_codec, clock_rate_id);
codec.clock_rate = JavaToNativeOptionalInt(jni, j_clock_rate);
jobject j_num_channels =
GetNullableObjectField(jni, j_codec, num_channels_id);
codec.num_channels = JavaToNativeOptionalInt(jni, j_num_channels);
parameters.codecs.push_back(codec);
}
return parameters;
}
jobject NativeToJavaRtpParameters(JNIEnv* jni,
const RtpParameters& parameters) {
jclass parameters_class = jni->FindClass("org/webrtc/RtpParameters");
jmethodID parameters_ctor =
GetMethodID(jni, parameters_class, "<init>", "()V");
jobject j_parameters = jni->NewObject(parameters_class, parameters_ctor);
CHECK_EXCEPTION(jni) << "error during NewObject";
// Add encodings.
jclass encoding_class = jni->FindClass("org/webrtc/RtpParameters$Encoding");
jmethodID encoding_ctor = GetMethodID(jni, encoding_class, "<init>", "()V");
jfieldID encodings_id =
GetFieldID(jni, parameters_class, "encodings", "Ljava/util/List;");
jobject j_encodings = GetObjectField(jni, j_parameters, encodings_id);
jmethodID encodings_add = GetMethodID(jni, GetObjectClass(jni, j_encodings),
"add", "(Ljava/lang/Object;)Z");
jfieldID active_id = GetFieldID(jni, encoding_class, "active", "Z");
jfieldID bitrate_id =
GetFieldID(jni, encoding_class, "maxBitrateBps", "Ljava/lang/Integer;");
jfieldID ssrc_id =
GetFieldID(jni, encoding_class, "ssrc", "Ljava/lang/Long;");
jclass long_class = jni->FindClass("java/lang/Long");
jmethodID long_ctor = GetMethodID(jni, long_class, "<init>", "(J)V");
for (const RtpEncodingParameters& encoding : parameters.encodings) {
jobject j_encoding_parameters =
jni->NewObject(encoding_class, encoding_ctor);
CHECK_EXCEPTION(jni) << "error during NewObject";
jni->SetBooleanField(j_encoding_parameters, active_id, encoding.active);
CHECK_EXCEPTION(jni) << "error during SetBooleanField";
jni->SetObjectField(j_encoding_parameters, bitrate_id,
NativeToJavaInteger(jni, encoding.max_bitrate_bps));
if (encoding.ssrc) {
jobject j_ssrc_value = jni->NewObject(long_class, long_ctor,
static_cast<jlong>(*encoding.ssrc));
CHECK_EXCEPTION(jni) << "error during NewObject";
jni->SetObjectField(j_encoding_parameters, ssrc_id, j_ssrc_value);
CHECK_EXCEPTION(jni) << "error during SetObjectField";
}
jboolean added = jni->CallBooleanMethod(j_encodings, encodings_add,
j_encoding_parameters);
CHECK_EXCEPTION(jni) << "error during CallBooleanMethod";
RTC_CHECK(added);
}
// Add codecs.
jclass codec_class = jni->FindClass("org/webrtc/RtpParameters$Codec");
jmethodID codec_ctor = GetMethodID(jni, codec_class, "<init>", "()V");
jfieldID codecs_id =
GetFieldID(jni, parameters_class, "codecs", "Ljava/util/List;");
jobject j_codecs = GetObjectField(jni, j_parameters, codecs_id);
jmethodID codecs_add = GetMethodID(jni, GetObjectClass(jni, j_codecs), "add",
"(Ljava/lang/Object;)Z");
jfieldID payload_type_id = GetFieldID(jni, codec_class, "payloadType", "I");
jfieldID name_id = GetFieldID(jni, codec_class, "name", "Ljava/lang/String;");
jfieldID kind_id = GetFieldID(jni, codec_class, "kind",
"Lorg/webrtc/MediaStreamTrack$MediaType;");
jfieldID clock_rate_id =
GetFieldID(jni, codec_class, "clockRate", "Ljava/lang/Integer;");
jfieldID num_channels_id =
GetFieldID(jni, codec_class, "numChannels", "Ljava/lang/Integer;");
for (const RtpCodecParameters& codec : parameters.codecs) {
jobject j_codec = jni->NewObject(codec_class, codec_ctor);
CHECK_EXCEPTION(jni) << "error during NewObject";
jni->SetIntField(j_codec, payload_type_id, codec.payload_type);
CHECK_EXCEPTION(jni) << "error during SetIntField";
jni->SetObjectField(j_codec, name_id, NativeToJavaString(jni, codec.name));
CHECK_EXCEPTION(jni) << "error during SetObjectField";
jni->SetObjectField(j_codec, kind_id,
NativeToJavaMediaType(jni, codec.kind));
CHECK_EXCEPTION(jni) << "error during SetObjectField";
jni->SetObjectField(j_codec, clock_rate_id,
NativeToJavaInteger(jni, codec.clock_rate));
jni->SetObjectField(j_codec, num_channels_id,
NativeToJavaInteger(jni, codec.num_channels));
jboolean added = jni->CallBooleanMethod(j_codecs, codecs_add, j_codec);
CHECK_EXCEPTION(jni) << "error during CallBooleanMethod";
RTC_CHECK(added);
}
return j_parameters;
}
} // namespace jni
} // namespace webrtc

View File

@ -7,7 +7,9 @@
* in the file PATENTS. All contributing project authors may * in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "sdk/android/src/jni/pc/media_jni.h" #include "sdk/android/src/jni/pc/media.h"
#include <utility>
#include "api/video_codecs/video_decoder_factory.h" #include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder_factory.h" #include "api/video_codecs/video_encoder_factory.h"

View File

@ -8,8 +8,10 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef SDK_ANDROID_SRC_JNI_PC_MEDIA_JNI_H_ #ifndef SDK_ANDROID_SRC_JNI_PC_MEDIA_H_
#define SDK_ANDROID_SRC_JNI_PC_MEDIA_JNI_H_ #define SDK_ANDROID_SRC_JNI_PC_MEDIA_H_
#include <memory>
#include "rtc_base/scoped_ref_ptr.h" #include "rtc_base/scoped_ref_ptr.h"
@ -58,4 +60,4 @@ cricket::MediaEngineInterface* CreateMediaEngine(
} // namespace jni } // namespace jni
} // namespace webrtc } // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_PC_MEDIA_JNI_H_ #endif // SDK_ANDROID_SRC_JNI_PC_MEDIA_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "sdk/android/src/jni/pc/mediaconstraints_jni.h" #include "sdk/android/src/jni/pc/mediaconstraints.h"
#include "rtc_base/ptr_util.h" #include "rtc_base/ptr_util.h"
#include "sdk/android/generated_peerconnection_jni/jni/MediaConstraints_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/MediaConstraints_jni.h"

View File

@ -8,10 +8,11 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef SDK_ANDROID_SRC_JNI_PC_MEDIACONSTRAINTS_JNI_H_ #ifndef SDK_ANDROID_SRC_JNI_PC_MEDIACONSTRAINTS_H_
#define SDK_ANDROID_SRC_JNI_PC_MEDIACONSTRAINTS_JNI_H_ #define SDK_ANDROID_SRC_JNI_PC_MEDIACONSTRAINTS_H_
#include <jni.h> #include <jni.h>
#include <memory>
#include "api/mediaconstraintsinterface.h" #include "api/mediaconstraintsinterface.h"
@ -25,4 +26,4 @@ std::unique_ptr<MediaConstraintsInterface> JavaToNativeMediaConstraints(
} // namespace jni } // namespace jni
} // namespace webrtc } // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_PC_MEDIACONSTRAINTS_JNI_H_ #endif // SDK_ANDROID_SRC_JNI_PC_MEDIACONSTRAINTS_H_

View File

@ -9,19 +9,19 @@
*/ */
#include "api/mediastreaminterface.h" #include "api/mediastreaminterface.h"
#include "sdk/android/generated_peerconnection_jni/jni/MediaSource_jni.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
JNI_FUNCTION_DECLARATION(jobject, JNI_FUNCTION_DECLARATION(jobject,
MediaSource_nativeState, MediaSource_getNativeState,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jlong j_p) { jlong j_p) {
rtc::scoped_refptr<MediaSourceInterface> p( return Java_State_fromNativeIndex(
reinterpret_cast<MediaSourceInterface*>(j_p)); jni, reinterpret_cast<MediaSourceInterface*>(j_p)->state());
return JavaEnumFromIndexAndClassName(jni, "MediaSource$State", p->state());
} }
} // namespace jni } // namespace jni

View File

@ -8,12 +8,24 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "sdk/android/src/jni/pc/mediastreamtrack.h"
#include "api/mediastreaminterface.h" #include "api/mediastreaminterface.h"
#include "sdk/android/generated_peerconnection_jni/jni/MediaStreamTrack_jni.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
jobject NativeToJavaMediaType(JNIEnv* jni, cricket::MediaType media_type) {
return Java_MediaType_fromNativeIndex(jni, media_type);
}
cricket::MediaType JavaToNativeMediaType(JNIEnv* jni, jobject j_media_type) {
return static_cast<cricket::MediaType>(
Java_MediaType_getNative(jni, j_media_type));
}
JNI_FUNCTION_DECLARATION(jstring, JNI_FUNCTION_DECLARATION(jstring,
MediaStreamTrack_getNativeId, MediaStreamTrack_getNativeId,
JNIEnv* jni, JNIEnv* jni,
@ -45,9 +57,8 @@ JNI_FUNCTION_DECLARATION(jobject,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jlong j_p) { jlong j_p) {
return JavaEnumFromIndexAndClassName( return Java_State_fromNativeIndex(
jni, "MediaStreamTrack$State", jni, reinterpret_cast<MediaStreamTrackInterface*>(j_p)->state());
reinterpret_cast<MediaStreamTrackInterface*>(j_p)->state());
} }
JNI_FUNCTION_DECLARATION(jboolean, JNI_FUNCTION_DECLARATION(jboolean,

View File

@ -0,0 +1,27 @@
/*
* 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.
*/
#ifndef SDK_ANDROID_SRC_JNI_PC_MEDIASTREAMTRACK_H_
#define SDK_ANDROID_SRC_JNI_PC_MEDIASTREAMTRACK_H_
#include <jni.h>
#include "api/mediatypes.h"
namespace webrtc {
namespace jni {
jobject NativeToJavaMediaType(JNIEnv* jni, cricket::MediaType media_type);
cricket::MediaType JavaToNativeMediaType(JNIEnv* jni, jobject j_media_type);
} // namespace jni
} // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_PC_MEDIASTREAMTRACK_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "sdk/android/src/jni/pc/audio_jni.h" #include "sdk/android/src/jni/pc/audio.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "sdk/android/src/jni/pc/media_jni.h" #include "sdk/android/src/jni/pc/media.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "sdk/android/src/jni/pc/video_jni.h" #include "sdk/android/src/jni/pc/video.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {

View File

@ -10,9 +10,8 @@
#include "sdk/android/src/jni/pc/ownedfactoryandthreads.h" #include "sdk/android/src/jni/pc/ownedfactoryandthreads.h"
#include "rtc_base/logging.h"
#include "sdk/android/src/jni/classreferenceholder.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/pc/peerconnectionfactory.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
@ -22,44 +21,20 @@ PeerConnectionFactoryInterface* factoryFromJava(jlong j_p) {
} }
OwnedFactoryAndThreads::~OwnedFactoryAndThreads() { OwnedFactoryAndThreads::~OwnedFactoryAndThreads() {
CHECK_RELEASE(factory_); factory_->Release();
if (network_monitor_factory_ != nullptr) { if (network_monitor_factory_ != nullptr) {
rtc::NetworkMonitorFactory::ReleaseFactory(network_monitor_factory_); rtc::NetworkMonitorFactory::ReleaseFactory(network_monitor_factory_);
} }
} }
void OwnedFactoryAndThreads::JavaCallbackOnFactoryThreads() {
JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(jni);
jclass j_factory_class = FindClass(jni, "org/webrtc/PeerConnectionFactory");
jmethodID m = nullptr;
if (network_thread_->IsCurrent()) {
RTC_LOG(LS_INFO) << "Network thread JavaCallback";
m = GetStaticMethodID(jni, j_factory_class, "onNetworkThreadReady", "()V");
}
if (worker_thread_->IsCurrent()) {
RTC_LOG(LS_INFO) << "Worker thread JavaCallback";
m = GetStaticMethodID(jni, j_factory_class, "onWorkerThreadReady", "()V");
}
if (signaling_thread_->IsCurrent()) {
RTC_LOG(LS_INFO) << "Signaling thread JavaCallback";
m = GetStaticMethodID(jni, j_factory_class, "onSignalingThreadReady",
"()V");
}
if (m != nullptr) {
jni->CallStaticVoidMethod(j_factory_class, m);
CHECK_EXCEPTION(jni) << "error during JavaCallback::CallStaticVoidMethod";
}
}
void OwnedFactoryAndThreads::InvokeJavaCallbacksOnFactoryThreads() { void OwnedFactoryAndThreads::InvokeJavaCallbacksOnFactoryThreads() {
RTC_LOG(LS_INFO) << "InvokeJavaCallbacksOnFactoryThreads."; RTC_LOG(LS_INFO) << "InvokeJavaCallbacksOnFactoryThreads.";
network_thread_->Invoke<void>(RTC_FROM_HERE, network_thread_->Invoke<void>(RTC_FROM_HERE,
[this] { JavaCallbackOnFactoryThreads(); }); &PeerConnectionFactoryNetworkThreadReady);
worker_thread_->Invoke<void>(RTC_FROM_HERE, worker_thread_->Invoke<void>(RTC_FROM_HERE,
[this] { JavaCallbackOnFactoryThreads(); }); &PeerConnectionFactoryWorkerThreadReady);
signaling_thread_->Invoke<void>(RTC_FROM_HERE, signaling_thread_->Invoke<void>(RTC_FROM_HERE,
[this] { JavaCallbackOnFactoryThreads(); }); &PeerConnectionFactorySignalingThreadReady);
} }
} // namespace jni } // namespace jni

View File

@ -68,8 +68,6 @@ class OwnedFactoryAndThreads {
void InvokeJavaCallbacksOnFactoryThreads(); void InvokeJavaCallbacksOnFactoryThreads();
private: private:
void JavaCallbackOnFactoryThreads();
const std::unique_ptr<Thread> network_thread_; const std::unique_ptr<Thread> network_thread_;
const std::unique_ptr<Thread> worker_thread_; const std::unique_ptr<Thread> worker_thread_;
const std::unique_ptr<Thread> signaling_thread_; const std::unique_ptr<Thread> signaling_thread_;

View File

@ -42,27 +42,24 @@
#include "sdk/android/generated_peerconnection_jni/jni/MediaStream_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/MediaStream_jni.h"
#include "sdk/android/generated_peerconnection_jni/jni/PeerConnection_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/PeerConnection_jni.h"
#include "sdk/android/generated_peerconnection_jni/jni/RtpSender_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/RtpSender_jni.h"
#include "sdk/android/src/jni/classreferenceholder.h" #include "sdk/android/generated_peerconnection_jni/jni/TurnCustomizer_jni.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/pc/datachannel.h" #include "sdk/android/src/jni/pc/datachannel.h"
#include "sdk/android/src/jni/pc/java_native_conversion.h" #include "sdk/android/src/jni/pc/icecandidate.h"
#include "sdk/android/src/jni/pc/mediaconstraints_jni.h" #include "sdk/android/src/jni/pc/mediaconstraints.h"
#include "sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.h" #include "sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.h"
#include "sdk/android/src/jni/pc/sdpobserver_jni.h" #include "sdk/android/src/jni/pc/sdpobserver.h"
#include "sdk/android/src/jni/pc/statsobserver_jni.h" #include "sdk/android/src/jni/pc/sessiondescription.h"
#include "sdk/android/src/jni/pc/statsobserver.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
namespace { namespace {
rtc::scoped_refptr<PeerConnectionInterface> ExtractNativePC(JNIEnv* jni, PeerConnectionInterface* ExtractNativePC(JNIEnv* jni, jobject j_pc) {
jobject j_pc) { return reinterpret_cast<PeerConnectionInterface*>(
jfieldID native_pc_id = Java_PeerConnection_getNativePeerConnection(jni, j_pc));
GetFieldID(jni, GetObjectClass(jni, j_pc), "nativePeerConnection", "J");
jlong j_p = GetLongField(jni, j_pc, native_pc_id);
return rtc::scoped_refptr<PeerConnectionInterface>(
reinterpret_cast<PeerConnectionInterface*>(j_p));
} }
jobject NativeToJavaRtpSender(JNIEnv* env, jobject NativeToJavaRtpSender(JNIEnv* env,
@ -74,49 +71,23 @@ jobject NativeToJavaRtpSender(JNIEnv* env,
return Java_RtpSender_Constructor(env, jlongFromPointer(sender.release())); return Java_RtpSender_Constructor(env, jlongFromPointer(sender.release()));
} }
// Convenience, used since callbacks occur on the signaling thread, which may PeerConnectionInterface::IceServers JavaToNativeIceServers(
// be a non-Java thread. JNIEnv* jni,
JNIEnv* jni() { jobject j_ice_servers) {
return AttachCurrentThreadIfNeeded(); PeerConnectionInterface::IceServers ice_servers;
}
} // namespace
void JavaToNativeIceServers(JNIEnv* jni,
jobject j_ice_servers,
PeerConnectionInterface::IceServers* ice_servers) {
for (jobject j_ice_server : Iterable(jni, j_ice_servers)) { for (jobject j_ice_server : Iterable(jni, j_ice_servers)) {
jclass j_ice_server_class = GetObjectClass(jni, j_ice_server);
jfieldID j_ice_server_urls_id =
GetFieldID(jni, j_ice_server_class, "urls", "Ljava/util/List;");
jfieldID j_ice_server_username_id =
GetFieldID(jni, j_ice_server_class, "username", "Ljava/lang/String;");
jfieldID j_ice_server_password_id =
GetFieldID(jni, j_ice_server_class, "password", "Ljava/lang/String;");
jfieldID j_ice_server_tls_cert_policy_id =
GetFieldID(jni, j_ice_server_class, "tlsCertPolicy",
"Lorg/webrtc/PeerConnection$TlsCertPolicy;");
jobject j_ice_server_tls_cert_policy = jobject j_ice_server_tls_cert_policy =
GetObjectField(jni, j_ice_server, j_ice_server_tls_cert_policy_id); Java_IceServer_getTlsCertPolicy(jni, j_ice_server);
jfieldID j_ice_server_hostname_id = jobject urls = Java_IceServer_getUrls(jni, j_ice_server);
GetFieldID(jni, j_ice_server_class, "hostname", "Ljava/lang/String;"); jstring username = Java_IceServer_getUsername(jni, j_ice_server);
jfieldID j_ice_server_tls_alpn_protocols_id = GetFieldID( jstring password = Java_IceServer_getPassword(jni, j_ice_server);
jni, j_ice_server_class, "tlsAlpnProtocols", "Ljava/util/List;");
jfieldID j_ice_server_tls_elliptic_curves_id = GetFieldID(
jni, j_ice_server_class, "tlsEllipticCurves", "Ljava/util/List;");
jobject urls = GetObjectField(jni, j_ice_server, j_ice_server_urls_id);
jstring username = reinterpret_cast<jstring>(
GetObjectField(jni, j_ice_server, j_ice_server_username_id));
jstring password = reinterpret_cast<jstring>(
GetObjectField(jni, j_ice_server, j_ice_server_password_id));
PeerConnectionInterface::TlsCertPolicy tls_cert_policy = PeerConnectionInterface::TlsCertPolicy tls_cert_policy =
JavaToNativeTlsCertPolicy(jni, j_ice_server_tls_cert_policy); JavaToNativeTlsCertPolicy(jni, j_ice_server_tls_cert_policy);
jstring hostname = reinterpret_cast<jstring>( jstring hostname = Java_IceServer_getHostname(jni, j_ice_server);
GetObjectField(jni, j_ice_server, j_ice_server_hostname_id)); jobject tls_alpn_protocols =
jobject tls_alpn_protocols = GetNullableObjectField( Java_IceServer_getTlsAlpnProtocols(jni, j_ice_server);
jni, j_ice_server, j_ice_server_tls_alpn_protocols_id); jobject tls_elliptic_curves =
jobject tls_elliptic_curves = GetNullableObjectField( Java_IceServer_getTlsEllipticCurves(jni, j_ice_server);
jni, j_ice_server, j_ice_server_tls_elliptic_curves_id);
PeerConnectionInterface::IceServer server; PeerConnectionInterface::IceServer server;
server.urls = JavaToStdVectorStrings(jni, urls); server.urls = JavaToStdVectorStrings(jni, urls);
server.username = JavaToStdString(jni, username); server.username = JavaToStdString(jni, username);
@ -126,102 +97,33 @@ void JavaToNativeIceServers(JNIEnv* jni,
server.tls_alpn_protocols = JavaToStdVectorStrings(jni, tls_alpn_protocols); server.tls_alpn_protocols = JavaToStdVectorStrings(jni, tls_alpn_protocols);
server.tls_elliptic_curves = server.tls_elliptic_curves =
JavaToStdVectorStrings(jni, tls_elliptic_curves); JavaToStdVectorStrings(jni, tls_elliptic_curves);
ice_servers->push_back(server); ice_servers.push_back(server);
} }
return ice_servers;
} }
} // namespace
void JavaToNativeRTCConfiguration( void JavaToNativeRTCConfiguration(
JNIEnv* jni, JNIEnv* jni,
jobject j_rtc_config, jobject j_rtc_config,
PeerConnectionInterface::RTCConfiguration* rtc_config) { PeerConnectionInterface::RTCConfiguration* rtc_config) {
jclass j_rtc_config_class = GetObjectClass(jni, j_rtc_config);
jfieldID j_ice_transports_type_id =
GetFieldID(jni, j_rtc_config_class, "iceTransportsType",
"Lorg/webrtc/PeerConnection$IceTransportsType;");
jobject j_ice_transports_type = jobject j_ice_transports_type =
GetObjectField(jni, j_rtc_config, j_ice_transports_type_id); Java_RTCConfiguration_getIceTransportsType(jni, j_rtc_config);
jfieldID j_bundle_policy_id =
GetFieldID(jni, j_rtc_config_class, "bundlePolicy",
"Lorg/webrtc/PeerConnection$BundlePolicy;");
jobject j_bundle_policy = jobject j_bundle_policy =
GetObjectField(jni, j_rtc_config, j_bundle_policy_id); Java_RTCConfiguration_getBundlePolicy(jni, j_rtc_config);
jfieldID j_rtcp_mux_policy_id =
GetFieldID(jni, j_rtc_config_class, "rtcpMuxPolicy",
"Lorg/webrtc/PeerConnection$RtcpMuxPolicy;");
jobject j_rtcp_mux_policy = jobject j_rtcp_mux_policy =
GetObjectField(jni, j_rtc_config, j_rtcp_mux_policy_id); Java_RTCConfiguration_getRtcpMuxPolicy(jni, j_rtc_config);
jfieldID j_tcp_candidate_policy_id =
GetFieldID(jni, j_rtc_config_class, "tcpCandidatePolicy",
"Lorg/webrtc/PeerConnection$TcpCandidatePolicy;");
jobject j_tcp_candidate_policy = jobject j_tcp_candidate_policy =
GetObjectField(jni, j_rtc_config, j_tcp_candidate_policy_id); Java_RTCConfiguration_getTcpCandidatePolicy(jni, j_rtc_config);
jfieldID j_candidate_network_policy_id =
GetFieldID(jni, j_rtc_config_class, "candidateNetworkPolicy",
"Lorg/webrtc/PeerConnection$CandidateNetworkPolicy;");
jobject j_candidate_network_policy = jobject j_candidate_network_policy =
GetObjectField(jni, j_rtc_config, j_candidate_network_policy_id); Java_RTCConfiguration_getCandidateNetworkPolicy(jni, j_rtc_config);
jobject j_ice_servers =
jfieldID j_ice_servers_id = Java_RTCConfiguration_getIceServers(jni, j_rtc_config);
GetFieldID(jni, j_rtc_config_class, "iceServers", "Ljava/util/List;");
jobject j_ice_servers = GetObjectField(jni, j_rtc_config, j_ice_servers_id);
jfieldID j_audio_jitter_buffer_max_packets_id =
GetFieldID(jni, j_rtc_config_class, "audioJitterBufferMaxPackets", "I");
jfieldID j_audio_jitter_buffer_fast_accelerate_id = GetFieldID(
jni, j_rtc_config_class, "audioJitterBufferFastAccelerate", "Z");
jfieldID j_ice_connection_receiving_timeout_id =
GetFieldID(jni, j_rtc_config_class, "iceConnectionReceivingTimeout", "I");
jfieldID j_ice_backup_candidate_pair_ping_interval_id = GetFieldID(
jni, j_rtc_config_class, "iceBackupCandidatePairPingInterval", "I");
jfieldID j_continual_gathering_policy_id =
GetFieldID(jni, j_rtc_config_class, "continualGatheringPolicy",
"Lorg/webrtc/PeerConnection$ContinualGatheringPolicy;");
jobject j_continual_gathering_policy = jobject j_continual_gathering_policy =
GetObjectField(jni, j_rtc_config, j_continual_gathering_policy_id); Java_RTCConfiguration_getContinualGatheringPolicy(jni, j_rtc_config);
jfieldID j_ice_candidate_pool_size_id =
GetFieldID(jni, j_rtc_config_class, "iceCandidatePoolSize", "I");
jfieldID j_presume_writable_when_fully_relayed_id = GetFieldID(
jni, j_rtc_config_class, "presumeWritableWhenFullyRelayed", "Z");
jfieldID j_prune_turn_ports_id =
GetFieldID(jni, j_rtc_config_class, "pruneTurnPorts", "Z");
jfieldID j_ice_check_min_interval_id = GetFieldID(
jni, j_rtc_config_class, "iceCheckMinInterval", "Ljava/lang/Integer;");
jfieldID j_disable_ipv6_on_wifi_id =
GetFieldID(jni, j_rtc_config_class, "disableIPv6OnWifi", "Z");
jfieldID j_max_ipv6_networks_id =
GetFieldID(jni, j_rtc_config_class, "maxIPv6Networks", "I");
jfieldID j_ice_regather_interval_range_id =
GetFieldID(jni, j_rtc_config_class, "iceRegatherIntervalRange",
"Lorg/webrtc/PeerConnection$IntervalRange;");
jclass j_interval_range_class =
jni->FindClass("org/webrtc/PeerConnection$IntervalRange");
jmethodID get_min_id =
GetMethodID(jni, j_interval_range_class, "getMin", "()I");
jmethodID get_max_id =
GetMethodID(jni, j_interval_range_class, "getMax", "()I");
jfieldID j_turn_customizer_type_id = GetFieldID(
jni, j_rtc_config_class, "turnCustomizer", "Lorg/webrtc/TurnCustomizer;");
jobject j_turn_customizer = jobject j_turn_customizer =
GetNullableObjectField(jni, j_rtc_config, j_turn_customizer_type_id); Java_RTCConfiguration_getTurnCustomizer(jni, j_rtc_config);
jclass j_turn_customizer_class = jni->FindClass("org/webrtc/TurnCustomizer");
jfieldID j_native_turn_customizer_id =
GetFieldID(jni, j_turn_customizer_class, "nativeTurnCustomizer", "J");
rtc_config->type = JavaToNativeIceTransportsType(jni, j_ice_transports_type); rtc_config->type = JavaToNativeIceTransportsType(jni, j_ice_transports_type);
rtc_config->bundle_policy = JavaToNativeBundlePolicy(jni, j_bundle_policy); rtc_config->bundle_policy = JavaToNativeBundlePolicy(jni, j_bundle_policy);
@ -231,51 +133,60 @@ void JavaToNativeRTCConfiguration(
JavaToNativeTcpCandidatePolicy(jni, j_tcp_candidate_policy); JavaToNativeTcpCandidatePolicy(jni, j_tcp_candidate_policy);
rtc_config->candidate_network_policy = rtc_config->candidate_network_policy =
JavaToNativeCandidateNetworkPolicy(jni, j_candidate_network_policy); JavaToNativeCandidateNetworkPolicy(jni, j_candidate_network_policy);
JavaToNativeIceServers(jni, j_ice_servers, &rtc_config->servers); rtc_config->servers = JavaToNativeIceServers(jni, j_ice_servers);
rtc_config->audio_jitter_buffer_max_packets = rtc_config->audio_jitter_buffer_max_packets =
GetIntField(jni, j_rtc_config, j_audio_jitter_buffer_max_packets_id); Java_RTCConfiguration_getAudioJitterBufferMaxPackets(jni, j_rtc_config);
rtc_config->audio_jitter_buffer_fast_accelerate = GetBooleanField( rtc_config->audio_jitter_buffer_fast_accelerate =
jni, j_rtc_config, j_audio_jitter_buffer_fast_accelerate_id); Java_RTCConfiguration_getAudioJitterBufferFastAccelerate(jni,
j_rtc_config);
rtc_config->ice_connection_receiving_timeout = rtc_config->ice_connection_receiving_timeout =
GetIntField(jni, j_rtc_config, j_ice_connection_receiving_timeout_id); Java_RTCConfiguration_getIceConnectionReceivingTimeout(jni, j_rtc_config);
rtc_config->ice_backup_candidate_pair_ping_interval = GetIntField( rtc_config->ice_backup_candidate_pair_ping_interval =
jni, j_rtc_config, j_ice_backup_candidate_pair_ping_interval_id); Java_RTCConfiguration_getIceBackupCandidatePairPingInterval(jni,
j_rtc_config);
rtc_config->continual_gathering_policy = rtc_config->continual_gathering_policy =
JavaToNativeContinualGatheringPolicy(jni, j_continual_gathering_policy); JavaToNativeContinualGatheringPolicy(jni, j_continual_gathering_policy);
rtc_config->ice_candidate_pool_size = rtc_config->ice_candidate_pool_size =
GetIntField(jni, j_rtc_config, j_ice_candidate_pool_size_id); Java_RTCConfiguration_getIceCandidatePoolSize(jni, j_rtc_config);
rtc_config->prune_turn_ports = rtc_config->prune_turn_ports =
GetBooleanField(jni, j_rtc_config, j_prune_turn_ports_id); Java_RTCConfiguration_getPruneTurnPorts(jni, j_rtc_config);
rtc_config->presume_writable_when_fully_relayed = GetBooleanField( rtc_config->presume_writable_when_fully_relayed =
jni, j_rtc_config, j_presume_writable_when_fully_relayed_id); Java_RTCConfiguration_getPresumeWritableWhenFullyRelayed(jni,
j_rtc_config);
jobject j_ice_check_min_interval = jobject j_ice_check_min_interval =
GetNullableObjectField(jni, j_rtc_config, j_ice_check_min_interval_id); Java_RTCConfiguration_getIceCheckMinInterval(jni, j_rtc_config);
rtc_config->ice_check_min_interval = rtc_config->ice_check_min_interval =
JavaToNativeOptionalInt(jni, j_ice_check_min_interval); JavaToNativeOptionalInt(jni, j_ice_check_min_interval);
rtc_config->disable_ipv6_on_wifi = rtc_config->disable_ipv6_on_wifi =
GetBooleanField(jni, j_rtc_config, j_disable_ipv6_on_wifi_id); Java_RTCConfiguration_getDisableIPv6OnWifi(jni, j_rtc_config);
rtc_config->max_ipv6_networks = rtc_config->max_ipv6_networks =
GetIntField(jni, j_rtc_config, j_max_ipv6_networks_id); Java_RTCConfiguration_getMaxIPv6Networks(jni, j_rtc_config);
jobject j_ice_regather_interval_range = GetNullableObjectField( jobject j_ice_regather_interval_range =
jni, j_rtc_config, j_ice_regather_interval_range_id); Java_RTCConfiguration_getIceRegatherIntervalRange(jni, j_rtc_config);
if (!IsNull(jni, j_ice_regather_interval_range)) { if (!IsNull(jni, j_ice_regather_interval_range)) {
int min = jni->CallIntMethod(j_ice_regather_interval_range, get_min_id); int min = Java_IntervalRange_getMin(jni, j_ice_regather_interval_range);
int max = jni->CallIntMethod(j_ice_regather_interval_range, get_max_id); int max = Java_IntervalRange_getMax(jni, j_ice_regather_interval_range);
rtc_config->ice_regather_interval_range.emplace(min, max); rtc_config->ice_regather_interval_range.emplace(min, max);
} }
if (!IsNull(jni, j_turn_customizer)) { if (!IsNull(jni, j_turn_customizer)) {
rtc_config->turn_customizer = reinterpret_cast<webrtc::TurnCustomizer*>( rtc_config->turn_customizer = reinterpret_cast<webrtc::TurnCustomizer*>(
GetLongField(jni, j_turn_customizer, j_native_turn_customizer_id)); Java_TurnCustomizer_getNativeTurnCustomizer(jni, j_turn_customizer));
} }
} }
rtc::KeyType GetRtcConfigKeyType(JNIEnv* env, jobject j_rtc_config) {
return JavaToNativeKeyType(
env, Java_RTCConfiguration_getKeyType(env, j_rtc_config));
}
PeerConnectionObserverJni::PeerConnectionObserverJni(JNIEnv* jni, PeerConnectionObserverJni::PeerConnectionObserverJni(JNIEnv* jni,
jobject j_observer) jobject j_observer)
: j_observer_global_(jni, j_observer) {} : j_observer_global_(jni, j_observer) {}
PeerConnectionObserverJni::~PeerConnectionObserverJni() { PeerConnectionObserverJni::~PeerConnectionObserverJni() {
ScopedLocalRefFrame local_ref_frame(jni()); JNIEnv* env = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(env);
while (!remote_streams_.empty()) while (!remote_streams_.empty())
DisposeRemoteStream(remote_streams_.begin()); DisposeRemoteStream(remote_streams_.begin());
} }
@ -380,7 +291,8 @@ void PeerConnectionObserverJni::AddNativeVideoTrackToJavaStream(
void PeerConnectionObserverJni::OnAudioTrackAddedToStream( void PeerConnectionObserverJni::OnAudioTrackAddedToStream(
AudioTrackInterface* track, AudioTrackInterface* track,
MediaStreamInterface* stream) { MediaStreamInterface* stream) {
ScopedLocalRefFrame local_ref_frame(jni()); JNIEnv* env = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(env);
jobject j_stream = GetOrCreateJavaStream(stream); jobject j_stream = GetOrCreateJavaStream(stream);
AddNativeAudioTrackToJavaStream(track, j_stream); AddNativeAudioTrackToJavaStream(track, j_stream);
} }
@ -388,7 +300,8 @@ void PeerConnectionObserverJni::OnAudioTrackAddedToStream(
void PeerConnectionObserverJni::OnVideoTrackAddedToStream( void PeerConnectionObserverJni::OnVideoTrackAddedToStream(
VideoTrackInterface* track, VideoTrackInterface* track,
MediaStreamInterface* stream) { MediaStreamInterface* stream) {
ScopedLocalRefFrame local_ref_frame(jni()); JNIEnv* env = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(env);
jobject j_stream = GetOrCreateJavaStream(stream); jobject j_stream = GetOrCreateJavaStream(stream);
AddNativeVideoTrackToJavaStream(track, j_stream); AddNativeVideoTrackToJavaStream(track, j_stream);
} }
@ -489,10 +402,11 @@ jobject PeerConnectionObserverJni::GetOrCreateJavaStream(
// Java MediaStream holds one reference. Corresponding Release() is in // Java MediaStream holds one reference. Corresponding Release() is in
// MediaStream_free, triggered by MediaStream.dispose(). // MediaStream_free, triggered by MediaStream.dispose().
stream->AddRef(); stream->AddRef();
JNIEnv* env = AttachCurrentThreadIfNeeded();
jobject j_stream = jobject j_stream =
Java_MediaStream_Constructor(jni(), jlongFromPointer(stream.get())); Java_MediaStream_Constructor(env, jlongFromPointer(stream.get()));
remote_streams_[stream] = NewGlobalRef(jni(), j_stream); remote_streams_[stream] = NewGlobalRef(env, j_stream);
return j_stream; return j_stream;
} }
@ -764,32 +678,26 @@ JNI_FUNCTION_DECLARATION(void,
JNI_FUNCTION_DECLARATION(jobject, JNI_FUNCTION_DECLARATION(jobject,
PeerConnection_signalingState, PeerConnection_signalingState,
JNIEnv* jni, JNIEnv* env,
jobject j_pc) { jobject j_pc) {
PeerConnectionInterface::SignalingState state = return Java_SignalingState_fromNativeIndex(
ExtractNativePC(jni, j_pc)->signaling_state(); env, ExtractNativePC(env, j_pc)->signaling_state());
return JavaEnumFromIndexAndClassName(jni, "PeerConnection$SignalingState",
state);
} }
JNI_FUNCTION_DECLARATION(jobject, JNI_FUNCTION_DECLARATION(jobject,
PeerConnection_iceConnectionState, PeerConnection_iceConnectionState,
JNIEnv* jni, JNIEnv* env,
jobject j_pc) { jobject j_pc) {
PeerConnectionInterface::IceConnectionState state = return Java_IceConnectionState_fromNativeIndex(
ExtractNativePC(jni, j_pc)->ice_connection_state(); env, ExtractNativePC(env, j_pc)->ice_connection_state());
return JavaEnumFromIndexAndClassName(jni, "PeerConnection$IceConnectionState",
state);
} }
JNI_FUNCTION_DECLARATION(jobject, JNI_FUNCTION_DECLARATION(jobject,
PeerConnection_iceGatheringState, PeerConnection_iceGatheringState,
JNIEnv* jni, JNIEnv* env,
jobject j_pc) { jobject j_pc) {
PeerConnectionInterface::IceGatheringState state = return Java_IceGatheringState_fromNativeIndex(
ExtractNativePC(jni, j_pc)->ice_gathering_state(); env, ExtractNativePC(env, j_pc)->ice_gathering_state());
return JavaEnumFromIndexAndClassName(jni, "PeerConnection$IceGatheringState",
state);
} }
JNI_FUNCTION_DECLARATION(void, JNI_FUNCTION_DECLARATION(void,

View File

@ -18,21 +18,19 @@
#include "api/peerconnectioninterface.h" #include "api/peerconnectioninterface.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/pc/mediaconstraints_jni.h" #include "sdk/android/src/jni/pc/mediaconstraints.h"
#include "sdk/android/src/jni/pc/rtpreceiver.h" #include "sdk/android/src/jni/pc/rtpreceiver.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
void JavaToNativeIceServers(JNIEnv* jni,
jobject j_ice_servers,
PeerConnectionInterface::IceServers* ice_servers);
void JavaToNativeRTCConfiguration( void JavaToNativeRTCConfiguration(
JNIEnv* jni, JNIEnv* jni,
jobject j_rtc_config, jobject j_rtc_config,
PeerConnectionInterface::RTCConfiguration* rtc_config); PeerConnectionInterface::RTCConfiguration* rtc_config);
rtc::KeyType GetRtcConfigKeyType(JNIEnv* env, jobject j_rtc_config);
// Adapter between the C++ PeerConnectionObserver interface and the Java // Adapter between the C++ PeerConnectionObserver interface and the Java
// PeerConnection.Observer interface. Wraps an instance of the Java interface // PeerConnection.Observer interface. Wraps an instance of the Java interface
// and dispatches C++ callbacks to Java. // and dispatches C++ callbacks to Java.

View File

@ -8,6 +8,8 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "sdk/android/src/jni/pc/peerconnectionfactory.h"
#include <memory> #include <memory>
#include <utility> #include <utility>
@ -23,14 +25,15 @@
#include "rtc_base/event_tracer.h" #include "rtc_base/event_tracer.h"
#include "rtc_base/stringutils.h" #include "rtc_base/stringutils.h"
#include "rtc_base/thread.h" #include "rtc_base/thread.h"
#include "sdk/android/generated_peerconnection_jni/jni/PeerConnectionFactory_jni.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/pc/androidnetworkmonitor_jni.h" #include "sdk/android/src/jni/pc/androidnetworkmonitor.h"
#include "sdk/android/src/jni/pc/audio_jni.h" #include "sdk/android/src/jni/pc/audio.h"
#include "sdk/android/src/jni/pc/java_native_conversion.h" #include "sdk/android/src/jni/pc/icecandidate.h"
#include "sdk/android/src/jni/pc/media_jni.h" #include "sdk/android/src/jni/pc/media.h"
#include "sdk/android/src/jni/pc/ownedfactoryandthreads.h" #include "sdk/android/src/jni/pc/ownedfactoryandthreads.h"
#include "sdk/android/src/jni/pc/peerconnection.h" #include "sdk/android/src/jni/pc/peerconnection.h"
#include "sdk/android/src/jni/pc/video_jni.h" #include "sdk/android/src/jni/pc/video.h"
#include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/field_trial.h"
// Adding 'nogncheck' to disable the gn include headers check. // Adding 'nogncheck' to disable the gn include headers check.
// We don't want to depend on 'system_wrappers:field_trial_default' because // We don't want to depend on 'system_wrappers:field_trial_default' because
@ -40,10 +43,29 @@
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
namespace {
PeerConnectionFactoryInterface::Options
JavaToNativePeerConnectionFactoryOptions(JNIEnv* jni, jobject options) {
int network_ignore_mask = Java_Options_getNetworkIgnoreMask(jni, options);
bool disable_encryption = Java_Options_getDisableEncryption(jni, options);
bool disable_network_monitor =
Java_Options_getDisableNetworkMonitor(jni, options);
PeerConnectionFactoryInterface::Options native_options;
// This doesn't necessarily match the c++ version of this struct; feel free
// to add more parameters as necessary.
native_options.network_ignore_mask = network_ignore_mask;
native_options.disable_encryption = disable_encryption;
native_options.disable_network_monitor = disable_network_monitor;
return native_options;
}
} // namespace
// Note: Some of the video-specific PeerConnectionFactory methods are // Note: Some of the video-specific PeerConnectionFactory methods are
// implemented in "video_jni.cc". This is done so that if an application // implemented in "video.cc". This is done so that if an application
// doesn't need video support, it can just link with "null_video_jni.cc" // doesn't need video support, it can just link with "null_video.cc"
// instead of "video_jni.cc", which doesn't bring in the video-specific // instead of "video.cc", which doesn't bring in the video-specific
// dependencies. // dependencies.
// Field trials initialization string // Field trials initialization string
@ -53,8 +75,26 @@ static char* field_trials_init_string = nullptr;
static bool factory_static_initialized = false; static bool factory_static_initialized = false;
static bool video_hw_acceleration_enabled = true; static bool video_hw_acceleration_enabled = true;
void PeerConnectionFactoryNetworkThreadReady() {
RTC_LOG(LS_INFO) << "Network thread JavaCallback";
JNIEnv* env = AttachCurrentThreadIfNeeded();
Java_PeerConnectionFactory_onNetworkThreadReady(env);
}
void PeerConnectionFactoryWorkerThreadReady() {
RTC_LOG(LS_INFO) << "Worker thread JavaCallback";
JNIEnv* env = AttachCurrentThreadIfNeeded();
Java_PeerConnectionFactory_onWorkerThreadReady(env);
}
void PeerConnectionFactorySignalingThreadReady() {
RTC_LOG(LS_INFO) << "Signaling thread JavaCallback";
JNIEnv* env = AttachCurrentThreadIfNeeded();
Java_PeerConnectionFactory_onSignalingThreadReady(env);
}
JNI_FUNCTION_DECLARATION(jlong, JNI_FUNCTION_DECLARATION(jlong,
PeerConnectionFactory_nativeCreateObserver, PeerConnectionFactory_createNativeObserver,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jobject j_observer) { jobject j_observer) {
@ -62,7 +102,7 @@ JNI_FUNCTION_DECLARATION(jlong,
} }
JNI_FUNCTION_DECLARATION(void, JNI_FUNCTION_DECLARATION(void,
PeerConnectionFactory_nativeInitializeAndroidGlobals, PeerConnectionFactory_initializeNativeAndroidGlobals,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jobject context, jobject context,
@ -93,14 +133,14 @@ JNI_FUNCTION_DECLARATION(void,
} }
JNI_FUNCTION_DECLARATION(void, JNI_FUNCTION_DECLARATION(void,
PeerConnectionFactory_nativeInitializeInternalTracer, PeerConnectionFactory_initializeNativeInternalTracer,
JNIEnv* jni, JNIEnv* jni,
jclass) { jclass) {
rtc::tracing::SetupInternalTracer(); rtc::tracing::SetupInternalTracer();
} }
JNI_FUNCTION_DECLARATION(jstring, JNI_FUNCTION_DECLARATION(jstring,
PeerConnectionFactory_nativeFieldTrialsFindFullName, PeerConnectionFactory_findNativeFieldTrialsFullName,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jstring j_name) { jstring j_name) {
@ -132,7 +172,7 @@ JNI_FUNCTION_DECLARATION(void,
} }
JNI_FUNCTION_DECLARATION(void, JNI_FUNCTION_DECLARATION(void,
PeerConnectionFactory_nativeShutdownInternalTracer, PeerConnectionFactory_shutdownNativeInternalTracer,
JNIEnv* jni, JNIEnv* jni,
jclass) { jclass) {
rtc::tracing::ShutdownInternalTracer(); rtc::tracing::ShutdownInternalTracer();
@ -252,7 +292,7 @@ jlong CreatePeerConnectionFactoryForJava(
JNI_FUNCTION_DECLARATION( JNI_FUNCTION_DECLARATION(
jlong, jlong,
PeerConnectionFactory_nativeCreatePeerConnectionFactory, PeerConnectionFactory_createNativePeerConnectionFactory,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jobject joptions, jobject joptions,
@ -265,7 +305,7 @@ JNI_FUNCTION_DECLARATION(
JNI_FUNCTION_DECLARATION( JNI_FUNCTION_DECLARATION(
jlong, jlong,
PeerConnectionFactory_nativeCreatePeerConnectionFactoryWithAudioProcessing, PeerConnectionFactory_createNativePeerConnectionFactoryWithAudioProcessing,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jobject joptions, jobject joptions,
@ -280,7 +320,7 @@ JNI_FUNCTION_DECLARATION(
} }
JNI_FUNCTION_DECLARATION(void, JNI_FUNCTION_DECLARATION(void,
PeerConnectionFactory_nativeFreeFactory, PeerConnectionFactory_freeNativeFactory,
JNIEnv*, JNIEnv*,
jclass, jclass,
jlong j_p) { jlong j_p) {
@ -293,7 +333,7 @@ JNI_FUNCTION_DECLARATION(void,
} }
JNI_FUNCTION_DECLARATION(void, JNI_FUNCTION_DECLARATION(void,
PeerConnectionFactory_nativeThreadsCallbacks, PeerConnectionFactory_invokeNativeThreadsCallbacks,
JNIEnv*, JNIEnv*,
jclass, jclass,
jlong j_p) { jlong j_p) {
@ -303,7 +343,7 @@ JNI_FUNCTION_DECLARATION(void,
} }
JNI_FUNCTION_DECLARATION(jlong, JNI_FUNCTION_DECLARATION(jlong,
PeerConnectionFactory_nativeCreateLocalMediaStream, PeerConnectionFactory_createNativeLocalMediaStream,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jlong native_factory, jlong native_factory,
@ -316,7 +356,7 @@ JNI_FUNCTION_DECLARATION(jlong,
} }
JNI_FUNCTION_DECLARATION(jlong, JNI_FUNCTION_DECLARATION(jlong,
PeerConnectionFactory_nativeCreateAudioSource, PeerConnectionFactory_createNativeAudioSource,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jlong native_factory, jlong native_factory,
@ -333,7 +373,7 @@ JNI_FUNCTION_DECLARATION(jlong,
} }
JNI_FUNCTION_DECLARATION(jlong, JNI_FUNCTION_DECLARATION(jlong,
PeerConnectionFactory_nativeCreateAudioTrack, PeerConnectionFactory_createNativeAudioTrack,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jlong native_factory, jlong native_factory,
@ -348,7 +388,7 @@ JNI_FUNCTION_DECLARATION(jlong,
} }
JNI_FUNCTION_DECLARATION(jboolean, JNI_FUNCTION_DECLARATION(jboolean,
PeerConnectionFactory_nativeStartAecDump, PeerConnectionFactory_startNativeAecDump,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jlong native_factory, jlong native_factory,
@ -360,7 +400,7 @@ JNI_FUNCTION_DECLARATION(jboolean,
} }
JNI_FUNCTION_DECLARATION(void, JNI_FUNCTION_DECLARATION(void,
PeerConnectionFactory_nativeStopAecDump, PeerConnectionFactory_stopNativeAecDump,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jlong native_factory) { jlong native_factory) {
@ -370,7 +410,7 @@ JNI_FUNCTION_DECLARATION(void,
} }
JNI_FUNCTION_DECLARATION(void, JNI_FUNCTION_DECLARATION(void,
PeerConnectionFactory_nativeSetOptions, PeerConnectionFactory_setNativeOptions,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jlong native_factory, jlong native_factory,
@ -393,7 +433,7 @@ JNI_FUNCTION_DECLARATION(void,
} }
JNI_FUNCTION_DECLARATION(jlong, JNI_FUNCTION_DECLARATION(jlong,
PeerConnectionFactory_nativeCreatePeerConnection, PeerConnectionFactory_createNativePeerConnection,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jlong factory, jlong factory,
@ -408,13 +448,8 @@ JNI_FUNCTION_DECLARATION(jlong,
PeerConnectionInterface::RTCConfigurationType::kAggressive); PeerConnectionInterface::RTCConfigurationType::kAggressive);
JavaToNativeRTCConfiguration(jni, j_rtc_config, &rtc_config); JavaToNativeRTCConfiguration(jni, j_rtc_config, &rtc_config);
jclass j_rtc_config_class = GetObjectClass(jni, j_rtc_config);
jfieldID j_key_type_id = GetFieldID(jni, j_rtc_config_class, "keyType",
"Lorg/webrtc/PeerConnection$KeyType;");
jobject j_key_type = GetObjectField(jni, j_rtc_config, j_key_type_id);
// Generate non-default certificate. // Generate non-default certificate.
rtc::KeyType key_type = JavaToNativeKeyType(jni, j_key_type); rtc::KeyType key_type = GetRtcConfigKeyType(jni, j_rtc_config);
if (key_type != rtc::KT_DEFAULT) { if (key_type != rtc::KT_DEFAULT) {
rtc::scoped_refptr<rtc::RTCCertificate> certificate = rtc::scoped_refptr<rtc::RTCCertificate> certificate =
rtc::RTCCertificateGenerator::GenerateCertificate( rtc::RTCCertificateGenerator::GenerateCertificate(

View File

@ -0,0 +1,26 @@
/*
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef SDK_ANDROID_SRC_JNI_PC_PEERCONNECTIONFACTORY_H_
#define SDK_ANDROID_SRC_JNI_PC_PEERCONNECTIONFACTORY_H_
#include <jni.h>
namespace webrtc {
namespace jni {
void PeerConnectionFactoryNetworkThreadReady();
void PeerConnectionFactoryWorkerThreadReady();
void PeerConnectionFactorySignalingThreadReady();
} // namespace jni
} // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_PC_PEERCONNECTIONFACTORY_H_

View File

@ -18,7 +18,6 @@
#include "sdk/android/generated_peerconnection_jni/jni/RTCStatsCollectorCallback_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/RTCStatsCollectorCallback_jni.h"
#include "sdk/android/generated_peerconnection_jni/jni/RTCStatsReport_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/RTCStatsReport_jni.h"
#include "sdk/android/generated_peerconnection_jni/jni/RTCStats_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/RTCStats_jni.h"
#include "sdk/android/src/jni/classreferenceholder.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
@ -116,8 +115,8 @@ jobject NativeToJavaRtcStatsReport(
const rtc::scoped_refptr<const RTCStatsReport>& report) { const rtc::scoped_refptr<const RTCStatsReport>& report) {
jobject j_stats_map = jobject j_stats_map =
NativeToJavaMap(env, *report, [](JNIEnv* env, const RTCStats& stats) { NativeToJavaMap(env, *report, [](JNIEnv* env, const RTCStats& stats) {
return std::pair<jobject, jobject>(NativeToJavaString(env, stats.id()), return std::make_pair(NativeToJavaString(env, stats.id()),
NativeToJavaRtcStats(env, stats)); NativeToJavaRtcStats(env, stats));
}); });
return Java_RTCStatsReport_create(env, report->timestamp_us(), j_stats_map); return Java_RTCStatsReport_create(env, report->timestamp_us(), j_stats_map);
} }

View File

@ -0,0 +1,84 @@
/*
* 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.
*/
#include "sdk/android/src/jni/pc/rtpparameters.h"
#include "sdk/android/generated_peerconnection_jni/jni/RtpParameters_jni.h"
#include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/pc/mediastreamtrack.h"
namespace webrtc {
namespace jni {
namespace {
jobject NativeToJavaRtpEncodingParameter(
JNIEnv* env,
const RtpEncodingParameters& encoding) {
return Java_Encoding_Constructor(
env, encoding.active, NativeToJavaInteger(env, encoding.max_bitrate_bps),
encoding.ssrc ? NativeToJavaLong(env, *encoding.ssrc) : nullptr);
}
jobject NativeToJavaRtpCodecParameter(JNIEnv* env,
const RtpCodecParameters& codec) {
return Java_Codec_Constructor(env, codec.payload_type,
NativeToJavaString(env, codec.name),
NativeToJavaMediaType(env, codec.kind),
NativeToJavaInteger(env, codec.clock_rate),
NativeToJavaInteger(env, codec.num_channels));
}
} // namespace
RtpParameters JavaToNativeRtpParameters(JNIEnv* jni, jobject j_parameters) {
RtpParameters parameters;
// Convert encodings.
jobject j_encodings = Java_RtpParameters_getEncodings(jni, j_parameters);
for (jobject j_encoding_parameters : Iterable(jni, j_encodings)) {
RtpEncodingParameters encoding;
encoding.active = Java_Encoding_getActive(jni, j_encoding_parameters);
jobject j_bitrate =
Java_Encoding_getMaxBitrateBps(jni, j_encoding_parameters);
encoding.max_bitrate_bps = JavaToNativeOptionalInt(jni, j_bitrate);
jobject j_ssrc = Java_Encoding_getSsrc(jni, j_encoding_parameters);
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)) {
RtpCodecParameters codec;
codec.payload_type = Java_Codec_getPayloadType(jni, j_codec);
codec.name = JavaToStdString(jni, Java_Codec_getName(jni, j_codec));
codec.kind = JavaToNativeMediaType(jni, Java_Codec_getKind(jni, j_codec));
codec.clock_rate =
JavaToNativeOptionalInt(jni, Java_Codec_getClockRate(jni, j_codec));
codec.num_channels =
JavaToNativeOptionalInt(jni, Java_Codec_getNumChannels(jni, j_codec));
parameters.codecs.push_back(codec);
}
return parameters;
}
jobject NativeToJavaRtpParameters(JNIEnv* env,
const RtpParameters& parameters) {
return Java_RtpParameters_Constructor(
env,
NativeToJavaList(env, parameters.encodings,
&NativeToJavaRtpEncodingParameter),
NativeToJavaList(env, parameters.codecs, &NativeToJavaRtpCodecParameter));
}
} // namespace jni
} // namespace webrtc

View File

@ -0,0 +1,27 @@
/*
* 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.
*/
#ifndef SDK_ANDROID_SRC_JNI_PC_RTPPARAMETERS_H_
#define SDK_ANDROID_SRC_JNI_PC_RTPPARAMETERS_H_
#include <jni.h>
#include "api/rtpparameters.h"
namespace webrtc {
namespace jni {
RtpParameters JavaToNativeRtpParameters(JNIEnv* jni, jobject j_parameters);
jobject NativeToJavaRtpParameters(JNIEnv* jni, const RtpParameters& parameters);
} // namespace jni
} // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_PC_RTPPARAMETERS_H_

View File

@ -12,7 +12,8 @@
#include "sdk/android/generated_peerconnection_jni/jni/RtpReceiver_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/RtpReceiver_jni.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/pc/java_native_conversion.h" #include "sdk/android/src/jni/pc/mediastreamtrack.h"
#include "sdk/android/src/jni/pc/rtpparameters.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {

View File

@ -10,7 +10,7 @@
#include "api/rtpsenderinterface.h" #include "api/rtpsenderinterface.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/pc/java_native_conversion.h" #include "sdk/android/src/jni/pc/rtpparameters.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {

View File

@ -0,0 +1,64 @@
/*
* 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.
*/
#include "sdk/android/src/jni/pc/sdpobserver.h"
#include <utility>
#include "api/mediaconstraintsinterface.h"
#include "sdk/android/generated_peerconnection_jni/jni/SdpObserver_jni.h"
#include "sdk/android/src/jni/jni_helpers.h"
namespace webrtc {
namespace jni {
CreateSdpObserverJni::CreateSdpObserverJni(
JNIEnv* env,
jobject j_observer,
std::unique_ptr<MediaConstraintsInterface> constraints)
: j_observer_global_(env, j_observer),
constraints_(std::move(constraints)) {}
void CreateSdpObserverJni::OnSuccess(SessionDescriptionInterface* desc) {
JNIEnv* env = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(env);
Java_SdpObserver_onCreateSuccess(env, *j_observer_global_,
NativeToJavaSessionDescription(env, desc));
// OnSuccess transfers ownership of the description (there's a TODO to make
// it use unique_ptr...).
delete desc;
}
void CreateSdpObserverJni::OnFailure(const std::string& error) {
JNIEnv* env = AttachCurrentThreadIfNeeded();
Java_SdpObserver_onCreateFailure(env, *j_observer_global_,
NativeToJavaString(env, error));
}
SetSdpObserverJni::SetSdpObserverJni(
JNIEnv* env,
jobject j_observer,
std::unique_ptr<MediaConstraintsInterface> constraints)
: j_observer_global_(env, j_observer),
constraints_(std::move(constraints)) {}
void SetSdpObserverJni::OnSuccess() {
JNIEnv* env = AttachCurrentThreadIfNeeded();
Java_SdpObserver_onSetSuccess(env, *j_observer_global_);
}
void SetSdpObserverJni::OnFailure(const std::string& error) {
JNIEnv* env = AttachCurrentThreadIfNeeded();
Java_SdpObserver_onSetFailure(env, *j_observer_global_,
NativeToJavaString(env, error));
}
} // namespace jni
} // namespace webrtc

View File

@ -0,0 +1,59 @@
/*
* 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.
*/
#ifndef SDK_ANDROID_SRC_JNI_PC_SDPOBSERVER_H_
#define SDK_ANDROID_SRC_JNI_PC_SDPOBSERVER_H_
#include <memory>
#include <string>
#include "api/peerconnectioninterface.h"
#include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/pc/sessiondescription.h"
namespace webrtc {
namespace jni {
class CreateSdpObserverJni : public CreateSessionDescriptionObserver {
public:
CreateSdpObserverJni(JNIEnv* env,
jobject j_observer,
std::unique_ptr<MediaConstraintsInterface> constraints);
MediaConstraintsInterface* constraints() { return constraints_.get(); }
void OnSuccess(SessionDescriptionInterface* desc) override;
void OnFailure(const std::string& error) override;
private:
const ScopedGlobalRef<jobject> j_observer_global_;
std::unique_ptr<MediaConstraintsInterface> constraints_;
};
class SetSdpObserverJni : public SetSessionDescriptionObserver {
public:
SetSdpObserverJni(JNIEnv* env,
jobject j_observer,
std::unique_ptr<MediaConstraintsInterface> constraints);
MediaConstraintsInterface* constraints() { return constraints_.get(); }
void OnSuccess() override;
void OnFailure(const std::string& error) override;
private:
const ScopedGlobalRef<jobject> j_observer_global_;
std::unique_ptr<MediaConstraintsInterface> constraints_;
};
} // namespace jni
} // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_PC_SDPOBSERVER_H_

View File

@ -1,110 +0,0 @@
/*
* 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.
*/
#ifndef SDK_ANDROID_SRC_JNI_PC_SDPOBSERVER_JNI_H_
#define SDK_ANDROID_SRC_JNI_PC_SDPOBSERVER_JNI_H_
#include <memory>
#include <string>
#include "api/peerconnectioninterface.h"
#include "sdk/android/src/jni/jni_helpers.h"
namespace webrtc {
namespace jni {
// Adapter for a Java StatsObserver presenting a C++
// CreateSessionDescriptionObserver or SetSessionDescriptionObserver and
// dispatching the callback from C++ back to Java.
template <class T> // T is one of {Create,Set}SessionDescriptionObserver.
class SdpObserverJni : public T {
public:
SdpObserverJni(JNIEnv* jni,
jobject j_observer,
std::unique_ptr<MediaConstraintsInterface> constraints)
: constraints_(std::move(constraints)),
j_observer_global_(jni, j_observer),
j_observer_class_(jni, GetObjectClass(jni, j_observer)) {}
virtual ~SdpObserverJni() {}
// Can't mark override because of templating.
virtual void OnSuccess() {
ScopedLocalRefFrame local_ref_frame(jni());
jmethodID m = GetMethodID(jni(), *j_observer_class_, "onSetSuccess", "()V");
jni()->CallVoidMethod(*j_observer_global_, m);
CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
}
// Can't mark override because of templating.
virtual void OnSuccess(SessionDescriptionInterface* desc) {
ScopedLocalRefFrame local_ref_frame(jni());
jmethodID m = GetMethodID(jni(), *j_observer_class_, "onCreateSuccess",
"(Lorg/webrtc/SessionDescription;)V");
jobject j_sdp = NativeToJavaSessionDescription(jni(), desc);
jni()->CallVoidMethod(*j_observer_global_, m, j_sdp);
CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
// OnSuccess transfers ownership of the description (there's a TODO to make
// it use unique_ptr...).
delete desc;
}
MediaConstraintsInterface* constraints() { return constraints_.get(); }
protected:
// Common implementation for failure of Set & Create types, distinguished by
// |op| being "Set" or "Create".
void DoOnFailure(const std::string& op, const std::string& error) {
jmethodID m = GetMethodID(jni(), *j_observer_class_, "on" + op + "Failure",
"(Ljava/lang/String;)V");
jstring j_error_string = NativeToJavaString(jni(), error);
jni()->CallVoidMethod(*j_observer_global_, m, j_error_string);
CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
}
JNIEnv* jni() { return AttachCurrentThreadIfNeeded(); }
private:
std::unique_ptr<MediaConstraintsInterface> constraints_;
const ScopedGlobalRef<jobject> j_observer_global_;
const ScopedGlobalRef<jclass> j_observer_class_;
};
class CreateSdpObserverJni
: public SdpObserverJni<CreateSessionDescriptionObserver> {
public:
CreateSdpObserverJni(JNIEnv* jni,
jobject j_observer,
std::unique_ptr<MediaConstraintsInterface> constraints)
: SdpObserverJni(jni, j_observer, std::move(constraints)) {}
void OnFailure(const std::string& error) override {
ScopedLocalRefFrame local_ref_frame(jni());
SdpObserverJni::DoOnFailure(std::string("Create"), error);
}
};
class SetSdpObserverJni : public SdpObserverJni<SetSessionDescriptionObserver> {
public:
SetSdpObserverJni(JNIEnv* jni,
jobject j_observer,
std::unique_ptr<MediaConstraintsInterface> constraints)
: SdpObserverJni(jni, j_observer, std::move(constraints)) {}
void OnFailure(const std::string& error) override {
ScopedLocalRefFrame local_ref_frame(jni());
SdpObserverJni::DoOnFailure(std::string("Set"), error);
}
};
} // namespace jni
} // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_PC_SDPOBSERVER_JNI_H_

View File

@ -0,0 +1,52 @@
/*
* 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.
*/
#include "sdk/android/src/jni/pc/sessiondescription.h"
#include <string>
#include "rtc_base/logging.h"
#include "sdk/android/generated_peerconnection_jni/jni/SessionDescription_jni.h"
#include "sdk/android/src/jni/jni_helpers.h"
namespace webrtc {
namespace jni {
std::unique_ptr<SessionDescriptionInterface> JavaToNativeSessionDescription(
JNIEnv* jni,
jobject j_sdp) {
std::string std_type = JavaToStdString(
jni, Java_SessionDescription_getTypeInCanonicalForm(jni, j_sdp));
std::string std_description =
JavaToStdString(jni, Java_SessionDescription_getDescription(jni, j_sdp));
rtc::Optional<SdpType> sdp_type_maybe = SdpTypeFromString(std_type);
if (!sdp_type_maybe) {
RTC_LOG(LS_ERROR) << "Unexpected SDP type: " << std_type;
return nullptr;
}
return CreateSessionDescription(*sdp_type_maybe, std_description);
}
jobject NativeToJavaSessionDescription(
JNIEnv* jni,
const SessionDescriptionInterface* desc) {
std::string sdp;
RTC_CHECK(desc->ToString(&sdp)) << "got so far: " << sdp;
jstring j_description = NativeToJavaString(jni, sdp);
jobject j_type =
Java_Type_fromCanonicalForm(jni, NativeToJavaString(jni, desc->type()));
jobject j_sdp =
Java_SessionDescription_Constructor(jni, j_type, j_description);
CHECK_EXCEPTION(jni) << "error during NewObject";
return j_sdp;
}
} // namespace jni
} // namespace webrtc

View File

@ -0,0 +1,32 @@
/*
* 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.
*/
#ifndef SDK_ANDROID_SRC_JNI_PC_SESSIONDESCRIPTION_H_
#define SDK_ANDROID_SRC_JNI_PC_SESSIONDESCRIPTION_H_
#include <jni.h>
#include <memory>
#include "api/jsep.h"
namespace webrtc {
namespace jni {
std::unique_ptr<SessionDescriptionInterface> JavaToNativeSessionDescription(
JNIEnv* jni,
jobject j_sdp);
jobject NativeToJavaSessionDescription(JNIEnv* jni,
const SessionDescriptionInterface* desc);
} // namespace jni
} // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_PC_SESSIONDESCRIPTION_H_

View File

@ -8,7 +8,9 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "sdk/android/src/jni/pc/statsobserver_jni.h" #include "sdk/android/src/jni/pc/statsobserver.h"
#include <vector>
#include "sdk/android/generated_peerconnection_jni/jni/StatsObserver_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/StatsObserver_jni.h"
#include "sdk/android/generated_peerconnection_jni/jni/StatsReport_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/StatsReport_jni.h"

View File

@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef SDK_ANDROID_SRC_JNI_PC_STATSOBSERVER_JNI_H_ #ifndef SDK_ANDROID_SRC_JNI_PC_STATSOBSERVER_H_
#define SDK_ANDROID_SRC_JNI_PC_STATSOBSERVER_JNI_H_ #define SDK_ANDROID_SRC_JNI_PC_STATSOBSERVER_H_
#include "api/peerconnectioninterface.h" #include "api/peerconnectioninterface.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
@ -32,4 +32,4 @@ class StatsObserverJni : public StatsObserver {
} // namespace jni } // namespace jni
} // namespace webrtc } // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_PC_STATSOBSERVER_JNI_H_ #endif // SDK_ANDROID_SRC_JNI_PC_STATSOBSERVER_H_

View File

@ -15,7 +15,7 @@ namespace webrtc {
namespace jni { namespace jni {
JNI_FUNCTION_DECLARATION(void, JNI_FUNCTION_DECLARATION(void,
TurnCustomizer_nativeFreeTurnCustomizer, TurnCustomizer_freeNativeTurnCustomizer,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jlong j_turn_customizer_pointer) { jlong j_turn_customizer_pointer) {

View File

@ -8,7 +8,10 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "sdk/android/src/jni/pc/video.h"
#include <jni.h> #include <jni.h>
#include <memory>
#include "api/video_codecs/video_decoder_factory.h" #include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder_factory.h" #include "api/video_codecs/video_encoder_factory.h"
@ -17,12 +20,12 @@
#include "media/engine/webrtcvideodecoderfactory.h" #include "media/engine/webrtcvideodecoderfactory.h"
#include "media/engine/webrtcvideoencoderfactory.h" #include "media/engine/webrtcvideoencoderfactory.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "sdk/android/generated_video_jni/jni/EglBase14_jni.h"
#include "sdk/android/src/jni/androidmediadecoder_jni.h" #include "sdk/android/src/jni/androidmediadecoder_jni.h"
#include "sdk/android/src/jni/androidmediaencoder_jni.h" #include "sdk/android/src/jni/androidmediaencoder_jni.h"
#include "sdk/android/src/jni/androidvideotracksource.h" #include "sdk/android/src/jni/androidvideotracksource.h"
#include "sdk/android/src/jni/classreferenceholder.h"
#include "sdk/android/src/jni/pc/ownedfactoryandthreads.h" #include "sdk/android/src/jni/pc/ownedfactoryandthreads.h"
#include "sdk/android/src/jni/surfacetexturehelper_jni.h" #include "sdk/android/src/jni/surfacetexturehelper.h"
#include "sdk/android/src/jni/videodecoderfactorywrapper.h" #include "sdk/android/src/jni/videodecoderfactorywrapper.h"
#include "sdk/android/src/jni/videoencoderfactorywrapper.h" #include "sdk/android/src/jni/videoencoderfactorywrapper.h"
@ -71,7 +74,7 @@ jobject GetJavaSurfaceTextureHelper(
} }
JNI_FUNCTION_DECLARATION(jlong, JNI_FUNCTION_DECLARATION(jlong,
PeerConnectionFactory_nativeCreateVideoSource, PeerConnectionFactory_createNativeVideoSource,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jlong native_factory, jlong native_factory,
@ -92,7 +95,7 @@ JNI_FUNCTION_DECLARATION(jlong,
} }
JNI_FUNCTION_DECLARATION(jlong, JNI_FUNCTION_DECLARATION(jlong,
PeerConnectionFactory_nativeCreateVideoTrack, PeerConnectionFactory_createNativeVideoTrack,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jlong native_factory, jlong native_factory,
@ -108,7 +111,7 @@ JNI_FUNCTION_DECLARATION(jlong,
JNI_FUNCTION_DECLARATION( JNI_FUNCTION_DECLARATION(
void, void,
PeerConnectionFactory_nativeSetVideoHwAccelerationOptions, PeerConnectionFactory_setNativeVideoHwAccelerationOptions,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jlong native_factory, jlong native_factory,
@ -117,15 +120,12 @@ JNI_FUNCTION_DECLARATION(
OwnedFactoryAndThreads* owned_factory = OwnedFactoryAndThreads* owned_factory =
reinterpret_cast<OwnedFactoryAndThreads*>(native_factory); reinterpret_cast<OwnedFactoryAndThreads*>(native_factory);
jclass j_eglbase14_context_class =
FindClass(jni, "org/webrtc/EglBase14$Context");
if (owned_factory->legacy_encoder_factory()) { if (owned_factory->legacy_encoder_factory()) {
MediaCodecVideoEncoderFactory* encoder_factory = MediaCodecVideoEncoderFactory* encoder_factory =
static_cast<MediaCodecVideoEncoderFactory*>( static_cast<MediaCodecVideoEncoderFactory*>(
owned_factory->legacy_encoder_factory()); owned_factory->legacy_encoder_factory());
if (encoder_factory && if (encoder_factory &&
jni->IsInstanceOf(local_egl_context, j_eglbase14_context_class)) { Java_Context_isEgl14Context(jni, local_egl_context)) {
RTC_LOG(LS_INFO) << "Set EGL context for HW encoding."; RTC_LOG(LS_INFO) << "Set EGL context for HW encoding.";
encoder_factory->SetEGLContext(jni, local_egl_context); encoder_factory->SetEGLContext(jni, local_egl_context);
} }

View File

@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef SDK_ANDROID_SRC_JNI_PC_VIDEO_JNI_H_ #ifndef SDK_ANDROID_SRC_JNI_PC_VIDEO_H_
#define SDK_ANDROID_SRC_JNI_PC_VIDEO_JNI_H_ #define SDK_ANDROID_SRC_JNI_PC_VIDEO_H_
#include <jni.h> #include <jni.h>
@ -50,4 +50,4 @@ jobject GetJavaSurfaceTextureHelper(
} // namespace jni } // namespace jni
} // namespace webrtc } // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_PC_VIDEO_JNI_H_ #endif // SDK_ANDROID_SRC_JNI_PC_VIDEO_H_

View File

@ -8,8 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "sdk/android/src/jni/surfacetexturehelper.h"
#include "sdk/android/src/jni/surfacetexturehelper_jni.h"
#include "rtc_base/bind.h" #include "rtc_base/bind.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
@ -18,6 +17,18 @@
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
void SurfaceTextureHelperTextureToYUV(JNIEnv* env,
jobject j_surface_texture_helper,
jobject 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));
}
rtc::scoped_refptr<SurfaceTextureHelper> SurfaceTextureHelper::create( rtc::scoped_refptr<SurfaceTextureHelper> SurfaceTextureHelper::create(
JNIEnv* jni, JNIEnv* jni,
const char* thread_name, const char* thread_name,

View File

@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef SDK_ANDROID_SRC_JNI_SURFACETEXTUREHELPER_JNI_H_ #ifndef SDK_ANDROID_SRC_JNI_SURFACETEXTUREHELPER_H_
#define SDK_ANDROID_SRC_JNI_SURFACETEXTUREHELPER_JNI_H_ #define SDK_ANDROID_SRC_JNI_SURFACETEXTUREHELPER_H_
#include <jni.h> #include <jni.h>
@ -42,8 +42,8 @@ namespace jni {
class SurfaceTextureHelper : public rtc::RefCountInterface { class SurfaceTextureHelper : public rtc::RefCountInterface {
public: public:
// Might return null if creating the Java SurfaceTextureHelper fails. // Might return null if creating the Java SurfaceTextureHelper fails.
static rtc::scoped_refptr<SurfaceTextureHelper> create( static rtc::scoped_refptr<SurfaceTextureHelper>
JNIEnv* jni, const char* thread_name, jobject j_egl_context); create(JNIEnv* jni, const char* thread_name, jobject j_egl_context);
jobject GetJavaSurfaceTextureHelper() const; jobject GetJavaSurfaceTextureHelper() const;
@ -63,7 +63,15 @@ class SurfaceTextureHelper : public rtc::RefCountInterface {
const ScopedGlobalRef<jobject> j_surface_texture_helper_; const ScopedGlobalRef<jobject> 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);
} // namespace jni } // namespace jni
} // namespace webrtc } // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_SURFACETEXTUREHELPER_JNI_H_ #endif // SDK_ANDROID_SRC_JNI_SURFACETEXTUREHELPER_H_

View File

@ -12,7 +12,7 @@
#include "api/video/video_frame.h" #include "api/video/video_frame.h"
#include "media/base/videosinkinterface.h" #include "media/base/videosinkinterface.h"
#include "sdk/android/src/jni/classreferenceholder.h" #include "sdk/android/generated_video_jni/jni/VideoRenderer_jni.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/videoframe.h" #include "sdk/android/src/jni/videoframe.h"
@ -24,28 +24,13 @@ namespace jni {
class JavaVideoRendererWrapper : public rtc::VideoSinkInterface<VideoFrame> { class JavaVideoRendererWrapper : public rtc::VideoSinkInterface<VideoFrame> {
public: public:
JavaVideoRendererWrapper(JNIEnv* jni, jobject j_callbacks) JavaVideoRendererWrapper(JNIEnv* jni, jobject j_callbacks)
: j_callbacks_(jni, j_callbacks), : j_callbacks_(jni, j_callbacks) {}
j_render_frame_id_(
GetMethodID(jni,
GetObjectClass(jni, j_callbacks),
"renderFrame",
"(Lorg/webrtc/VideoRenderer$I420Frame;)V")),
j_frame_class_(jni,
FindClass(jni, "org/webrtc/VideoRenderer$I420Frame")),
j_i420_frame_ctor_id_(GetMethodID(jni,
*j_frame_class_,
"<init>",
"(III[I[Ljava/nio/ByteBuffer;J)V")),
j_texture_frame_ctor_id_(
GetMethodID(jni, *j_frame_class_, "<init>", "(IIII[FJ)V")),
j_byte_buffer_class_(jni, FindClass(jni, "java/nio/ByteBuffer")) {
CHECK_EXCEPTION(jni);
}
virtual ~JavaVideoRendererWrapper() {} virtual ~JavaVideoRendererWrapper() {}
void OnFrame(const VideoFrame& video_frame) override { void OnFrame(const VideoFrame& video_frame) override {
ScopedLocalRefFrame local_ref_frame(jni()); JNIEnv* env = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(env);
jobject j_frame; jobject j_frame;
if (video_frame.video_frame_buffer()->type() == if (video_frame.video_frame_buffer()->type() ==
@ -55,84 +40,72 @@ class JavaVideoRendererWrapper : public rtc::VideoSinkInterface<VideoFrame> {
video_frame.video_frame_buffer().get()); video_frame.video_frame_buffer().get());
switch (android_buffer->android_type()) { switch (android_buffer->android_type()) {
case AndroidVideoFrameBuffer::AndroidType::kTextureBuffer: case AndroidVideoFrameBuffer::AndroidType::kTextureBuffer:
j_frame = ToJavaTextureFrame(&video_frame); j_frame = ToJavaTextureFrame(env, video_frame);
break; break;
case AndroidVideoFrameBuffer::AndroidType::kJavaBuffer: case AndroidVideoFrameBuffer::AndroidType::kJavaBuffer:
j_frame = static_cast<AndroidVideoBuffer*>(android_buffer) j_frame = FromWrappedJavaBuffer(env, video_frame);
->ToJavaI420Frame(jni(), video_frame.rotation());
break; break;
default: default:
RTC_NOTREACHED(); RTC_NOTREACHED();
} }
} else { } else {
j_frame = ToJavaI420Frame(&video_frame); j_frame = ToJavaI420Frame(env, video_frame);
} }
// |j_callbacks_| is responsible for releasing |j_frame| with // |j_callbacks_| is responsible for releasing |j_frame| with
// VideoRenderer.renderFrameDone(). // VideoRenderer.renderFrameDone().
jni()->CallVoidMethod(*j_callbacks_, j_render_frame_id_, j_frame); Java_Callbacks_renderFrame(env, *j_callbacks_, j_frame);
CHECK_EXCEPTION(jni());
} }
private: private:
// Make a shallow copy of |frame| to be used with Java. The callee has // Make a shallow copy of |frame| to be used with Java. The callee has
// ownership of the frame, and the frame should be released with // ownership of the frame, and the frame should be released with
// VideoRenderer.releaseNativeFrame(). // VideoRenderer.releaseNativeFrame().
static jlong javaShallowCopy(const VideoFrame* frame) { static jlong javaShallowCopy(const VideoFrame& frame) {
return jlongFromPointer(new VideoFrame(*frame)); return jlongFromPointer(new VideoFrame(frame));
} }
// Return a VideoRenderer.I420Frame referring to the data in |frame|. // Return a VideoRenderer.I420Frame referring to the data in |frame|.
jobject ToJavaI420Frame(const VideoFrame* frame) { jobject FromWrappedJavaBuffer(JNIEnv* env, const VideoFrame& frame) {
jintArray strides = jni()->NewIntArray(3); return Java_I420Frame_Constructor(
jint* strides_array = jni()->GetIntArrayElements(strides, NULL); env, frame.rotation(),
static_cast<AndroidVideoBuffer*>(frame.video_frame_buffer().get())
->video_frame_buffer(),
javaShallowCopy(frame));
}
// Return a VideoRenderer.I420Frame referring to the data in |frame|.
jobject ToJavaI420Frame(JNIEnv* env, const VideoFrame& frame) {
rtc::scoped_refptr<I420BufferInterface> i420_buffer = rtc::scoped_refptr<I420BufferInterface> i420_buffer =
frame->video_frame_buffer()->ToI420(); frame.video_frame_buffer()->ToI420();
strides_array[0] = i420_buffer->StrideY(); jobject y_buffer = env->NewDirectByteBuffer(
strides_array[1] = i420_buffer->StrideU();
strides_array[2] = i420_buffer->StrideV();
jni()->ReleaseIntArrayElements(strides, strides_array, 0);
jobjectArray planes = jni()->NewObjectArray(3, *j_byte_buffer_class_, NULL);
jobject y_buffer = jni()->NewDirectByteBuffer(
const_cast<uint8_t*>(i420_buffer->DataY()), const_cast<uint8_t*>(i420_buffer->DataY()),
i420_buffer->StrideY() * i420_buffer->height()); i420_buffer->StrideY() * i420_buffer->height());
size_t chroma_height = i420_buffer->ChromaHeight(); size_t chroma_height = i420_buffer->ChromaHeight();
jobject u_buffer = jobject u_buffer =
jni()->NewDirectByteBuffer(const_cast<uint8_t*>(i420_buffer->DataU()), env->NewDirectByteBuffer(const_cast<uint8_t*>(i420_buffer->DataU()),
i420_buffer->StrideU() * chroma_height); i420_buffer->StrideU() * chroma_height);
jobject v_buffer = jobject v_buffer =
jni()->NewDirectByteBuffer(const_cast<uint8_t*>(i420_buffer->DataV()), env->NewDirectByteBuffer(const_cast<uint8_t*>(i420_buffer->DataV()),
i420_buffer->StrideV() * chroma_height); i420_buffer->StrideV() * chroma_height);
return Java_I420Frame_createI420Frame(
jni()->SetObjectArrayElement(planes, 0, y_buffer); env, frame.width(), frame.height(), static_cast<int>(frame.rotation()),
jni()->SetObjectArrayElement(planes, 1, u_buffer); i420_buffer->StrideY(), y_buffer, i420_buffer->StrideU(), u_buffer,
jni()->SetObjectArrayElement(planes, 2, v_buffer); i420_buffer->StrideV(), v_buffer, javaShallowCopy(frame));
return jni()->NewObject(*j_frame_class_, j_i420_frame_ctor_id_,
frame->width(), frame->height(),
static_cast<int>(frame->rotation()), strides,
planes, javaShallowCopy(frame));
} }
// Return a VideoRenderer.I420Frame referring texture object in |frame|. // Return a VideoRenderer.I420Frame referring texture object in |frame|.
jobject ToJavaTextureFrame(const VideoFrame* frame) { jobject ToJavaTextureFrame(JNIEnv* env, const VideoFrame& frame) {
NativeHandleImpl handle = NativeHandleImpl handle =
static_cast<AndroidTextureBuffer*>(frame->video_frame_buffer().get()) static_cast<AndroidTextureBuffer*>(frame.video_frame_buffer().get())
->native_handle_impl(); ->native_handle_impl();
jfloatArray sampling_matrix = handle.sampling_matrix.ToJava(jni()); jfloatArray sampling_matrix = handle.sampling_matrix.ToJava(env);
return jni()->NewObject( return Java_I420Frame_createTextureFrame(
*j_frame_class_, j_texture_frame_ctor_id_, frame->width(), env, frame.width(), frame.height(), static_cast<int>(frame.rotation()),
frame->height(), static_cast<int>(frame->rotation()),
handle.oes_texture_id, sampling_matrix, javaShallowCopy(frame)); handle.oes_texture_id, sampling_matrix, javaShallowCopy(frame));
} }
JNIEnv* jni() { return AttachCurrentThreadIfNeeded(); }
ScopedGlobalRef<jobject> j_callbacks_; ScopedGlobalRef<jobject> j_callbacks_;
jmethodID j_render_frame_id_;
ScopedGlobalRef<jclass> j_frame_class_;
jmethodID j_i420_frame_ctor_id_;
jmethodID j_texture_frame_ctor_id_;
ScopedGlobalRef<jclass> j_byte_buffer_class_;
}; };
JNI_FUNCTION_DECLARATION(void, JNI_FUNCTION_DECLARATION(void,
@ -152,17 +125,17 @@ JNI_FUNCTION_DECLARATION(void,
} }
JNI_FUNCTION_DECLARATION(jlong, JNI_FUNCTION_DECLARATION(jlong,
VideoRenderer_nativeWrapVideoRenderer, VideoRenderer_createNativeVideoRenderer,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jobject j_callbacks) { jobject j_callbacks) {
std::unique_ptr<JavaVideoRendererWrapper> renderer( std::unique_ptr<JavaVideoRendererWrapper> renderer(
new JavaVideoRendererWrapper(jni, j_callbacks)); new JavaVideoRendererWrapper(jni, j_callbacks));
return (jlong)renderer.release(); return jlongFromPointer(renderer.release());
} }
JNI_FUNCTION_DECLARATION(void, JNI_FUNCTION_DECLARATION(void,
VideoRenderer_nativeCopyPlane, VideoRenderer_copyPlaneNative,
JNIEnv* jni, JNIEnv* jni,
jclass, jclass,
jobject j_src_buffer, jobject j_src_buffer,

View File

@ -10,47 +10,28 @@
#include "sdk/android/src/jni/videocodecinfo.h" #include "sdk/android/src/jni/videocodecinfo.h"
#include "sdk/android/src/jni/classreferenceholder.h" #include "sdk/android/generated_video_jni/jni/VideoCodecInfo_jni.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {
SdpVideoFormat VideoCodecInfoToSdpVideoFormat(JNIEnv* jni, jobject j_info) { SdpVideoFormat VideoCodecInfoToSdpVideoFormat(JNIEnv* jni, jobject j_info) {
jclass video_codec_info_class = FindClass(jni, "org/webrtc/VideoCodecInfo"); return SdpVideoFormat(
jfieldID name_field = JavaToStdString(jni, Java_VideoCodecInfo_getName(jni, j_info)),
GetFieldID(jni, video_codec_info_class, "name", "Ljava/lang/String;"); JavaToStdMapStrings(jni, Java_VideoCodecInfo_getParams(jni, j_info)));
jfieldID params_field =
GetFieldID(jni, video_codec_info_class, "params", "Ljava/util/Map;");
jobject j_params = jni->GetObjectField(j_info, params_field);
jstring j_name =
static_cast<jstring>(jni->GetObjectField(j_info, name_field));
return SdpVideoFormat(JavaToStdString(jni, j_name),
JavaToStdMapStrings(jni, j_params));
} }
jobject SdpVideoFormatToVideoCodecInfo(JNIEnv* jni, jobject SdpVideoFormatToVideoCodecInfo(JNIEnv* jni,
const SdpVideoFormat& format) { const SdpVideoFormat& format) {
jclass hash_map_class = jni->FindClass("java/util/HashMap"); jobject j_params = NativeToJavaMap(
jmethodID hash_map_constructor = jni, format.parameters,
jni->GetMethodID(hash_map_class, "<init>", "()V"); [](JNIEnv* env, const std::pair<std::string, std::string>& entry) {
jmethodID put_method = jni->GetMethodID( return std::make_pair(NativeToJavaString(env, entry.first),
hash_map_class, "put", NativeToJavaString(env, entry.second));
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); });
jclass video_codec_info_class = FindClass(jni, "org/webrtc/VideoCodecInfo"); return Java_VideoCodecInfo_Constructor(
jmethodID video_codec_info_constructor = jni->GetMethodID( jni, NativeToJavaString(jni, format.name), j_params);
video_codec_info_class, "<init>", "(Ljava/lang/String;Ljava/util/Map;)V");
jobject j_params = jni->NewObject(hash_map_class, hash_map_constructor);
for (auto const& param : format.parameters) {
jni->CallObjectMethod(j_params, put_method,
NativeToJavaString(jni, param.first),
NativeToJavaString(jni, param.second));
}
return jni->NewObject(video_codec_info_class, video_codec_info_constructor,
NativeToJavaString(jni, format.name), j_params);
} }
} // namespace jni } // namespace jni

View File

@ -14,6 +14,7 @@
#include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_decoder.h"
#include "common_types.h" // NOLINT(build/include) #include "common_types.h" // NOLINT(build/include)
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "sdk/android/generated_video_jni/jni/VideoDecoderFactory_jni.h"
#include "sdk/android/src/jni/wrappednativecodec.h" #include "sdk/android/src/jni/wrappednativecodec.h"
namespace webrtc { namespace webrtc {
@ -21,20 +22,14 @@ namespace jni {
VideoDecoderFactoryWrapper::VideoDecoderFactoryWrapper(JNIEnv* jni, VideoDecoderFactoryWrapper::VideoDecoderFactoryWrapper(JNIEnv* jni,
jobject decoder_factory) jobject decoder_factory)
: decoder_factory_(jni, decoder_factory) { : decoder_factory_(jni, decoder_factory) {}
jclass decoder_factory_class = jni->GetObjectClass(*decoder_factory_);
create_decoder_method_ =
jni->GetMethodID(decoder_factory_class, "createDecoder",
"(Ljava/lang/String;)Lorg/webrtc/VideoDecoder;");
}
std::unique_ptr<VideoDecoder> VideoDecoderFactoryWrapper::CreateVideoDecoder( std::unique_ptr<VideoDecoder> VideoDecoderFactoryWrapper::CreateVideoDecoder(
const SdpVideoFormat& format) { const SdpVideoFormat& format) {
JNIEnv* jni = AttachCurrentThreadIfNeeded(); JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(jni); ScopedLocalRefFrame local_ref_frame(jni);
jstring name = NativeToJavaString(jni, format.name); jobject decoder = Java_VideoDecoderFactory_createDecoder(
jobject decoder = jni, *decoder_factory_, NativeToJavaString(jni, format.name));
jni->CallObjectMethod(*decoder_factory_, create_decoder_method_, name);
return decoder != nullptr ? JavaToNativeVideoDecoder(jni, decoder) : nullptr; return decoder != nullptr ? JavaToNativeVideoDecoder(jni, decoder) : nullptr;
} }

View File

@ -31,7 +31,6 @@ class VideoDecoderFactoryWrapper : public VideoDecoderFactory {
private: private:
const ScopedGlobalRef<jobject> decoder_factory_; const ScopedGlobalRef<jobject> decoder_factory_;
jmethodID create_decoder_method_;
}; };
} // namespace jni } // namespace jni

View File

@ -17,7 +17,6 @@
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "sdk/android/generated_video_jni/jni/VideoDecoderWrapper_jni.h" #include "sdk/android/generated_video_jni/jni/VideoDecoderWrapper_jni.h"
#include "sdk/android/generated_video_jni/jni/VideoDecoder_jni.h" #include "sdk/android/generated_video_jni/jni/VideoDecoder_jni.h"
#include "sdk/android/src/jni/classreferenceholder.h"
#include "sdk/android/src/jni/encodedimage.h" #include "sdk/android/src/jni/encodedimage.h"
#include "sdk/android/src/jni/videocodecstatus.h" #include "sdk/android/src/jni/videocodecstatus.h"
#include "sdk/android/src/jni/videoframe.h" #include "sdk/android/src/jni/videoframe.h"

View File

@ -10,9 +10,9 @@
#include <jni.h> #include <jni.h>
#include "third_party/libyuv/include/libyuv/scale.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "third_party/libyuv/include/libyuv/scale.h"
namespace webrtc { namespace webrtc {
namespace jni { namespace jni {

View File

@ -20,8 +20,8 @@
#include "rtc_base/scoped_ref_ptr.h" #include "rtc_base/scoped_ref_ptr.h"
#include "rtc_base/timeutils.h" #include "rtc_base/timeutils.h"
#include "sdk/android/generated_video_jni/jni/VideoFrame_jni.h" #include "sdk/android/generated_video_jni/jni/VideoFrame_jni.h"
#include "sdk/android/src/jni/classreferenceholder.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/surfacetexturehelper.h"
#include "sdk/android/src/jni/wrapped_native_i420_buffer.h" #include "sdk/android/src/jni/wrapped_native_i420_buffer.h"
#include "system_wrappers/include/aligned_malloc.h" #include "system_wrappers/include/aligned_malloc.h"
#include "third_party/libyuv/include/libyuv/scale.h" #include "third_party/libyuv/include/libyuv/scale.h"
@ -268,20 +268,9 @@ rtc::scoped_refptr<I420BufferInterface> AndroidTextureBuffer::ToI420() {
// TODO(sakal): This call to a deperecated method will be removed when // TODO(sakal): This call to a deperecated method will be removed when
// AndroidTextureBuffer is removed. // AndroidTextureBuffer is removed.
jmethodID transform_mid = GetMethodID(
jni,
GetObjectClass(jni, surface_texture_helper_),
"textureToYUV",
"(Ljava/nio/ByteBuffer;IIII[F)V");
jobject byte_buffer = jni->NewDirectByteBuffer(y_data, size); jobject byte_buffer = jni->NewDirectByteBuffer(y_data, size);
SurfaceTextureHelperTextureToYUV(jni, surface_texture_helper_, byte_buffer,
jfloatArray sampling_matrix = native_handle_.sampling_matrix.ToJava(jni); width(), height(), stride, native_handle_);
jni->CallVoidMethod(surface_texture_helper_,
transform_mid,
byte_buffer, width(), height(), stride,
native_handle_.oes_texture_id, sampling_matrix);
CHECK_EXCEPTION(jni) << "textureToYUV throwed an exception";
return copy; return copy;
} }
@ -350,21 +339,6 @@ rtc::scoped_refptr<I420BufferInterface> AndroidVideoBuffer::ToI420() {
return AndroidVideoI420Buffer::Adopt(jni, width_, height_, j_i420_buffer); return AndroidVideoI420Buffer::Adopt(jni, width_, height_, j_i420_buffer);
} }
jobject AndroidVideoBuffer::ToJavaI420Frame(JNIEnv* jni, int rotation) {
jclass j_byte_buffer_class = jni->FindClass("java/nio/ByteBuffer");
jclass j_i420_frame_class =
FindClass(jni, "org/webrtc/VideoRenderer$I420Frame");
jmethodID j_i420_frame_ctor_id = GetMethodID(
jni, j_i420_frame_class, "<init>", "(ILorg/webrtc/VideoFrame$Buffer;J)V");
// Java code just uses the native frame to hold a reference to the buffer so
// this is okay.
VideoFrame* native_frame =
new VideoFrame(this, 0 /* timestamp */, 0 /* render_time_ms */,
VideoRotation::kVideoRotation_0 /* rotation */);
return jni->NewObject(j_i420_frame_class, j_i420_frame_ctor_id, rotation,
*j_video_frame_buffer_, jlongFromPointer(native_frame));
}
VideoFrame JavaToNativeFrame(JNIEnv* jni, VideoFrame JavaToNativeFrame(JNIEnv* jni,
jobject j_video_frame, jobject j_video_frame,
uint32_t timestamp_rtp) { uint32_t timestamp_rtp) {

View File

@ -130,9 +130,6 @@ class AndroidVideoBuffer : public AndroidVideoFrameBuffer {
int scale_width, int scale_width,
int scale_height); int scale_height);
// Returns an instance of VideoRenderer.I420Frame (deprecated)
jobject ToJavaI420Frame(JNIEnv* jni, int rotation);
protected: protected:
// Should not be called directly. Adopts the Java VideoFrame.Buffer. Use // Should not be called directly. Adopts the Java VideoFrame.Buffer. Use
// Create() or Adopt() instead for clarity. // Create() or Adopt() instead for clarity.

View File

@ -13,7 +13,6 @@
#include "api/mediastreaminterface.h" #include "api/mediastreaminterface.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "sdk/android/generated_video_jni/jni/VideoSink_jni.h" #include "sdk/android/generated_video_jni/jni/VideoSink_jni.h"
#include "sdk/android/src/jni/classreferenceholder.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/videoframe.h" #include "sdk/android/src/jni/videoframe.h"

View File

@ -10,7 +10,7 @@
#include "sdk/android/src/jni/wrapped_native_i420_buffer.h" #include "sdk/android/src/jni/wrapped_native_i420_buffer.h"
#include "sdk/android/src/jni/classreferenceholder.h" #include "sdk/android/generated_video_jni/jni/WrappedNativeI420Buffer_jni.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
namespace webrtc { namespace webrtc {
@ -20,13 +20,6 @@ namespace jni {
jobject WrapI420Buffer( jobject WrapI420Buffer(
JNIEnv* jni, JNIEnv* jni,
const rtc::scoped_refptr<I420BufferInterface>& i420_buffer) { const rtc::scoped_refptr<I420BufferInterface>& i420_buffer) {
jclass j_wrapped_native_i420_buffer_class =
FindClass(jni, "org/webrtc/WrappedNativeI420Buffer");
jmethodID j_wrapped_native_i420_buffer_ctor_id =
GetMethodID(jni, j_wrapped_native_i420_buffer_class, "<init>",
"(IILjava/nio/ByteBuffer;ILjava/nio/ByteBuffer;ILjava/nio/"
"ByteBuffer;IJ)V");
jobject y_buffer = jobject y_buffer =
jni->NewDirectByteBuffer(const_cast<uint8_t*>(i420_buffer->DataY()), jni->NewDirectByteBuffer(const_cast<uint8_t*>(i420_buffer->DataY()),
i420_buffer->StrideY() * i420_buffer->height()); i420_buffer->StrideY() * i420_buffer->height());
@ -37,12 +30,11 @@ jobject WrapI420Buffer(
const_cast<uint8_t*>(i420_buffer->DataV()), const_cast<uint8_t*>(i420_buffer->DataV()),
i420_buffer->StrideV() * i420_buffer->ChromaHeight()); i420_buffer->StrideV() * i420_buffer->ChromaHeight());
jobject j_wrapped_native_i420_buffer = jni->NewObject( jobject j_wrapped_native_i420_buffer =
j_wrapped_native_i420_buffer_class, j_wrapped_native_i420_buffer_ctor_id, Java_WrappedNativeI420Buffer_Constructor(
i420_buffer->width(), i420_buffer->height(), y_buffer, jni, i420_buffer->width(), i420_buffer->height(), y_buffer,
i420_buffer->StrideY(), u_buffer, i420_buffer->StrideU(), v_buffer, i420_buffer->StrideY(), u_buffer, i420_buffer->StrideU(), v_buffer,
i420_buffer->StrideV(), jlongFromPointer(i420_buffer.get())); i420_buffer->StrideV(), jlongFromPointer(i420_buffer.get()));
CHECK_EXCEPTION(jni);
return j_wrapped_native_i420_buffer; return j_wrapped_native_i420_buffer;
} }