OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2013 The WebRTC project authors. All Rights Reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 | |
12 package org.webrtc; | |
13 | |
14 import java.util.List; | |
15 | |
16 /** | |
17 * Java wrapper for a C++ PeerConnectionFactoryInterface. Main entry point to | |
18 * the PeerConnection API for clients. | |
19 */ | |
20 public class PeerConnectionFactory { | |
21 static { | |
22 System.loadLibrary("jingle_peerconnection_so"); | |
23 } | |
24 | |
25 private static final String TAG = "PeerConnectionFactory"; | |
26 private final long nativeFactory; | |
27 private static Thread networkThread; | |
28 private static Thread workerThread; | |
29 private static Thread signalingThread; | |
30 private EglBase localEglbase; | |
31 private EglBase remoteEglbase; | |
32 | |
33 public static class Options { | |
34 // Keep in sync with webrtc/base/network.h! | |
35 static final int ADAPTER_TYPE_UNKNOWN = 0; | |
36 static final int ADAPTER_TYPE_ETHERNET = 1 << 0; | |
37 static final int ADAPTER_TYPE_WIFI = 1 << 1; | |
38 static final int ADAPTER_TYPE_CELLULAR = 1 << 2; | |
39 static final int ADAPTER_TYPE_VPN = 1 << 3; | |
40 static final int ADAPTER_TYPE_LOOPBACK = 1 << 4; | |
41 | |
42 public int networkIgnoreMask; | |
43 public boolean disableEncryption; | |
44 public boolean disableNetworkMonitor; | |
45 } | |
46 | |
47 // |context| is an android.content.Context object, but we keep it untyped here | |
48 // to allow building on non-Android platforms. | |
49 // Callers may specify either |initializeAudio| or |initializeVideo| as false | |
50 // to skip initializing the respective engine (and avoid the need for the | |
51 // respective permissions). | |
52 // |renderEGLContext| can be provided to suport HW video decoding to | |
53 // texture and will be used to create a shared EGL context on video | |
54 // decoding thread. | |
55 public static native boolean initializeAndroidGlobals( | |
56 Object context, boolean initializeAudio, boolean initializeVideo, | |
57 boolean videoHwAcceleration); | |
58 | |
59 // Field trial initialization. Must be called before PeerConnectionFactory | |
60 // is created. | |
61 public static native void initializeFieldTrials(String fieldTrialsInitString); | |
62 // Internal tracing initialization. Must be called before PeerConnectionFactor
y is created to | |
63 // prevent racing with tracing code. | |
64 public static native void initializeInternalTracer(); | |
65 // Internal tracing shutdown, called to prevent resource leaks. Must be called
after | |
66 // PeerConnectionFactory is gone to prevent races with code performing tracing
. | |
67 public static native void shutdownInternalTracer(); | |
68 // Start/stop internal capturing of internal tracing. | |
69 public static native boolean startInternalTracingCapture(String tracing_filena
me); | |
70 public static native void stopInternalTracingCapture(); | |
71 | |
72 @Deprecated | |
73 public PeerConnectionFactory() { | |
74 this(null); | |
75 } | |
76 | |
77 public PeerConnectionFactory(Options options) { | |
78 nativeFactory = nativeCreatePeerConnectionFactory(options); | |
79 if (nativeFactory == 0) { | |
80 throw new RuntimeException("Failed to initialize PeerConnectionFactory!"); | |
81 } | |
82 } | |
83 | |
84 public PeerConnection createPeerConnection( | |
85 PeerConnection.RTCConfiguration rtcConfig, | |
86 MediaConstraints constraints, | |
87 PeerConnection.Observer observer) { | |
88 long nativeObserver = nativeCreateObserver(observer); | |
89 if (nativeObserver == 0) { | |
90 return null; | |
91 } | |
92 long nativePeerConnection = nativeCreatePeerConnection( | |
93 nativeFactory, rtcConfig, constraints, nativeObserver); | |
94 if (nativePeerConnection == 0) { | |
95 return null; | |
96 } | |
97 return new PeerConnection(nativePeerConnection, nativeObserver); | |
98 } | |
99 | |
100 public PeerConnection createPeerConnection( | |
101 List<PeerConnection.IceServer> iceServers, | |
102 MediaConstraints constraints, | |
103 PeerConnection.Observer observer) { | |
104 PeerConnection.RTCConfiguration rtcConfig = | |
105 new PeerConnection.RTCConfiguration(iceServers); | |
106 return createPeerConnection(rtcConfig, constraints, observer); | |
107 } | |
108 | |
109 public MediaStream createLocalMediaStream(String label) { | |
110 return new MediaStream( | |
111 nativeCreateLocalMediaStream(nativeFactory, label)); | |
112 } | |
113 | |
114 // The VideoSource takes ownership of |capturer|, so capturer.release() should
not be called | |
115 // manually after this. | |
116 public VideoSource createVideoSource( | |
117 VideoCapturer capturer, MediaConstraints constraints) { | |
118 final EglBase.Context eglContext = | |
119 localEglbase == null ? null : localEglbase.getEglBaseContext(); | |
120 return new VideoSource(nativeCreateVideoSource(nativeFactory, | |
121 eglContext, capturer, constraints)); | |
122 } | |
123 | |
124 public VideoTrack createVideoTrack(String id, VideoSource source) { | |
125 return new VideoTrack(nativeCreateVideoTrack( | |
126 nativeFactory, id, source.nativeSource)); | |
127 } | |
128 | |
129 public AudioSource createAudioSource(MediaConstraints constraints) { | |
130 return new AudioSource(nativeCreateAudioSource(nativeFactory, constraints)); | |
131 } | |
132 | |
133 public AudioTrack createAudioTrack(String id, AudioSource source) { | |
134 return new AudioTrack(nativeCreateAudioTrack( | |
135 nativeFactory, id, source.nativeSource)); | |
136 } | |
137 | |
138 // Starts recording an AEC dump. Ownership of the file is transfered to the | |
139 // native code. If an AEC dump is already in progress, it will be stopped and | |
140 // a new one will start using the provided file. | |
141 public boolean startAecDump(int file_descriptor, int filesize_limit_bytes) { | |
142 return nativeStartAecDump(nativeFactory, file_descriptor, filesize_limit_byt
es); | |
143 } | |
144 | |
145 // Stops recording an AEC dump. If no AEC dump is currently being recorded, | |
146 // this call will have no effect. | |
147 public void stopAecDump() { | |
148 nativeStopAecDump(nativeFactory); | |
149 } | |
150 | |
151 // Starts recording an RTC event log. Ownership of the file is transfered to | |
152 // the native code. If an RTC event log is already being recorded, it will be | |
153 // stopped and a new one will start using the provided file. | |
154 public boolean startRtcEventLog(int file_descriptor) { | |
155 return startRtcEventLog(file_descriptor, -1); | |
156 } | |
157 | |
158 // Same as above, but allows setting an upper limit to the size of the | |
159 // generated logfile. | |
160 public boolean startRtcEventLog(int file_descriptor, | |
161 int filesize_limit_bytes) { | |
162 return nativeStartRtcEventLog(nativeFactory, | |
163 file_descriptor, | |
164 filesize_limit_bytes); | |
165 } | |
166 | |
167 // Stops recording an RTC event log. If no RTC event log is currently being | |
168 // recorded, this call will have no effect. | |
169 public void stopRtcEventLog() { | |
170 nativeStopRtcEventLog(nativeFactory); | |
171 } | |
172 | |
173 @Deprecated | |
174 public void setOptions(Options options) { | |
175 nativeSetOptions(nativeFactory, options); | |
176 } | |
177 | |
178 /** Set the EGL context used by HW Video encoding and decoding. | |
179 * | |
180 * @param localEglContext Must be the same as used by VideoCapturerAndroid a
nd any local video | |
181 * renderer. | |
182 * @param remoteEglContext Must be the same as used by any remote video rende
rer. | |
183 */ | |
184 public void setVideoHwAccelerationOptions(EglBase.Context localEglContext, | |
185 EglBase.Context remoteEglContext) { | |
186 if (localEglbase != null) { | |
187 Logging.w(TAG, "Egl context already set."); | |
188 localEglbase.release(); | |
189 } | |
190 if (remoteEglbase != null) { | |
191 Logging.w(TAG, "Egl context already set."); | |
192 remoteEglbase.release(); | |
193 } | |
194 localEglbase = EglBase.create(localEglContext); | |
195 remoteEglbase = EglBase.create(remoteEglContext); | |
196 nativeSetVideoHwAccelerationOptions(nativeFactory, localEglbase.getEglBaseCo
ntext(), | |
197 remoteEglbase.getEglBaseContext()); | |
198 } | |
199 | |
200 public void dispose() { | |
201 nativeFreeFactory(nativeFactory); | |
202 networkThread = null; | |
203 workerThread = null; | |
204 signalingThread = null; | |
205 if (localEglbase != null) | |
206 localEglbase.release(); | |
207 if (remoteEglbase != null) | |
208 remoteEglbase.release(); | |
209 } | |
210 | |
211 public void threadsCallbacks() { | |
212 nativeThreadsCallbacks(nativeFactory); | |
213 } | |
214 | |
215 private static void printStackTrace(Thread thread, String threadName) { | |
216 if (thread != null) { | |
217 StackTraceElement[] stackTraces = thread.getStackTrace(); | |
218 if (stackTraces.length > 0) { | |
219 Logging.d(TAG, threadName + " stacks trace:"); | |
220 for (StackTraceElement stackTrace : stackTraces) { | |
221 Logging.d(TAG, stackTrace.toString()); | |
222 } | |
223 } | |
224 } | |
225 } | |
226 | |
227 public static void printStackTraces() { | |
228 printStackTrace(networkThread, "Network thread"); | |
229 printStackTrace(workerThread, "Worker thread"); | |
230 printStackTrace(signalingThread, "Signaling thread"); | |
231 } | |
232 | |
233 private static void onNetworkThreadReady() { | |
234 networkThread = Thread.currentThread(); | |
235 Logging.d(TAG, "onNetworkThreadReady"); | |
236 } | |
237 | |
238 private static void onWorkerThreadReady() { | |
239 workerThread = Thread.currentThread(); | |
240 Logging.d(TAG, "onWorkerThreadReady"); | |
241 } | |
242 | |
243 private static void onSignalingThreadReady() { | |
244 signalingThread = Thread.currentThread(); | |
245 Logging.d(TAG, "onSignalingThreadReady"); | |
246 } | |
247 | |
248 private static native long nativeCreatePeerConnectionFactory(Options options); | |
249 | |
250 private static native long nativeCreateObserver( | |
251 PeerConnection.Observer observer); | |
252 | |
253 private static native long nativeCreatePeerConnection( | |
254 long nativeFactory, PeerConnection.RTCConfiguration rtcConfig, | |
255 MediaConstraints constraints, long nativeObserver); | |
256 | |
257 private static native long nativeCreateLocalMediaStream( | |
258 long nativeFactory, String label); | |
259 | |
260 private static native long nativeCreateVideoSource( | |
261 long nativeFactory, EglBase.Context eglContext, VideoCapturer videoCapture
r, | |
262 MediaConstraints constraints); | |
263 | |
264 private static native long nativeCreateVideoTrack( | |
265 long nativeFactory, String id, long nativeVideoSource); | |
266 | |
267 private static native long nativeCreateAudioSource( | |
268 long nativeFactory, MediaConstraints constraints); | |
269 | |
270 private static native long nativeCreateAudioTrack( | |
271 long nativeFactory, String id, long nativeSource); | |
272 | |
273 private static native boolean nativeStartAecDump( | |
274 long nativeFactory, int file_descriptor, int filesize_limit_bytes); | |
275 | |
276 private static native void nativeStopAecDump(long nativeFactory); | |
277 | |
278 private static native boolean nativeStartRtcEventLog(long nativeFactory, | |
279 int file_descriptor, | |
280 int filesize_limit_bytes)
; | |
281 | |
282 private static native void nativeStopRtcEventLog(long nativeFactory); | |
283 | |
284 @Deprecated | |
285 public native void nativeSetOptions(long nativeFactory, Options options); | |
286 | |
287 private static native void nativeSetVideoHwAccelerationOptions( | |
288 long nativeFactory, Object localEGLContext, Object remoteEGLContext); | |
289 | |
290 private static native void nativeThreadsCallbacks(long nativeFactory); | |
291 | |
292 private static native void nativeFreeFactory(long nativeFactory); | |
293 } | |
OLD | NEW |