Home | History | Annotate | Download | only in webrtc
      1 /*
      2  * libjingle
      3  * Copyright 2013 Google Inc.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are met:
      7  *
      8  *  1. Redistributions of source code must retain the above copyright notice,
      9  *     this list of conditions and the following disclaimer.
     10  *  2. Redistributions in binary form must reproduce the above copyright notice,
     11  *     this list of conditions and the following disclaimer in the documentation
     12  *     and/or other materials provided with the distribution.
     13  *  3. The name of the author may not be used to endorse or promote products
     14  *     derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 
     29 package org.webrtc;
     30 
     31 import java.util.List;
     32 
     33 /**
     34  * Java wrapper for a C++ PeerConnectionFactoryInterface.  Main entry point to
     35  * the PeerConnection API for clients.
     36  */
     37 public class PeerConnectionFactory {
     38   static {
     39     System.loadLibrary("jingle_peerconnection_so");
     40   }
     41 
     42   private static final String TAG = "PeerConnectionFactory";
     43   private final long nativeFactory;
     44   private static Thread workerThread;
     45   private static Thread signalingThread;
     46 
     47   public static class Options {
     48     // Keep in sync with webrtc/base/network.h!
     49     static final int ADAPTER_TYPE_UNKNOWN = 0;
     50     static final int ADAPTER_TYPE_ETHERNET = 1 << 0;
     51     static final int ADAPTER_TYPE_WIFI = 1 << 1;
     52     static final int ADAPTER_TYPE_CELLULAR = 1 << 2;
     53     static final int ADAPTER_TYPE_VPN = 1 << 3;
     54     static final int ADAPTER_TYPE_LOOPBACK = 1 << 4;
     55 
     56     public int networkIgnoreMask;
     57     public boolean disableEncryption;
     58     public boolean disableNetworkMonitor;
     59   }
     60 
     61   // |context| is an android.content.Context object, but we keep it untyped here
     62   // to allow building on non-Android platforms.
     63   // Callers may specify either |initializeAudio| or |initializeVideo| as false
     64   // to skip initializing the respective engine (and avoid the need for the
     65   // respective permissions).
     66   // |renderEGLContext| can be provided to suport HW video decoding to
     67   // texture and will be used to create a shared EGL context on video
     68   // decoding thread.
     69   public static native boolean initializeAndroidGlobals(
     70       Object context, boolean initializeAudio, boolean initializeVideo,
     71       boolean videoHwAcceleration);
     72 
     73   // Field trial initialization. Must be called before PeerConnectionFactory
     74   // is created.
     75   public static native void initializeFieldTrials(String fieldTrialsInitString);
     76   // Internal tracing initialization. Must be called before PeerConnectionFactory is created to
     77   // prevent racing with tracing code.
     78   public static native void initializeInternalTracer();
     79   // Internal tracing shutdown, called to prevent resource leaks. Must be called after
     80   // PeerConnectionFactory is gone to prevent races with code performing tracing.
     81   public static native void shutdownInternalTracer();
     82   // Start/stop internal capturing of internal tracing.
     83   public static native boolean startInternalTracingCapture(String tracing_filename);
     84   public static native void stopInternalTracingCapture();
     85 
     86   public PeerConnectionFactory() {
     87     nativeFactory = nativeCreatePeerConnectionFactory();
     88     if (nativeFactory == 0) {
     89       throw new RuntimeException("Failed to initialize PeerConnectionFactory!");
     90     }
     91   }
     92 
     93   public PeerConnection createPeerConnection(
     94       PeerConnection.RTCConfiguration rtcConfig,
     95       MediaConstraints constraints,
     96       PeerConnection.Observer observer) {
     97     long nativeObserver = nativeCreateObserver(observer);
     98     if (nativeObserver == 0) {
     99       return null;
    100     }
    101     long nativePeerConnection = nativeCreatePeerConnection(
    102         nativeFactory, rtcConfig, constraints, nativeObserver);
    103     if (nativePeerConnection == 0) {
    104       return null;
    105     }
    106     return new PeerConnection(nativePeerConnection, nativeObserver);
    107   }
    108 
    109   public PeerConnection createPeerConnection(
    110       List<PeerConnection.IceServer> iceServers,
    111       MediaConstraints constraints,
    112       PeerConnection.Observer observer) {
    113     PeerConnection.RTCConfiguration rtcConfig =
    114         new PeerConnection.RTCConfiguration(iceServers);
    115     return createPeerConnection(rtcConfig, constraints, observer);
    116   }
    117 
    118   public MediaStream createLocalMediaStream(String label) {
    119     return new MediaStream(
    120         nativeCreateLocalMediaStream(nativeFactory, label));
    121   }
    122 
    123   public VideoSource createVideoSource(
    124       VideoCapturer capturer, MediaConstraints constraints) {
    125     return new VideoSource(nativeCreateVideoSource(
    126         nativeFactory, capturer.takeNativeVideoCapturer(), constraints));
    127   }
    128 
    129   public VideoTrack createVideoTrack(String id, VideoSource source) {
    130     return new VideoTrack(nativeCreateVideoTrack(
    131         nativeFactory, id, source.nativeSource));
    132   }
    133 
    134   public AudioSource createAudioSource(MediaConstraints constraints) {
    135     return new AudioSource(nativeCreateAudioSource(nativeFactory, constraints));
    136   }
    137 
    138   public AudioTrack createAudioTrack(String id, AudioSource source) {
    139     return new AudioTrack(nativeCreateAudioTrack(
    140         nativeFactory, id, source.nativeSource));
    141   }
    142 
    143   // Starts recording an AEC dump. Ownership of the file is transfered to the
    144   // native code. If an AEC dump is already in progress, it will be stopped and
    145   // a new one will start using the provided file.
    146   public boolean startAecDump(int file_descriptor) {
    147     return nativeStartAecDump(nativeFactory, file_descriptor);
    148   }
    149 
    150   // Stops recording an AEC dump. If no AEC dump is currently being recorded,
    151   // this call will have no effect.
    152   public void stopAecDump() {
    153     nativeStopAecDump(nativeFactory);
    154   }
    155 
    156   // Starts recording an RTC event log. Ownership of the file is transfered to
    157   // the native code. If an RTC event log is already being recorded, it will be
    158   // stopped and a new one will start using the provided file.
    159   public boolean startRtcEventLog(int file_descriptor) {
    160     return nativeStartRtcEventLog(nativeFactory, file_descriptor);
    161   }
    162 
    163   // Stops recording an RTC event log. If no RTC event log is currently being
    164   // recorded, this call will have no effect.
    165   public void StopRtcEventLog() {
    166     nativeStopRtcEventLog(nativeFactory);
    167   }
    168 
    169   public void setOptions(Options options) {
    170     nativeSetOptions(nativeFactory, options);
    171   }
    172 
    173   @Deprecated
    174   public void setVideoHwAccelerationOptions(Object renderEGLContext) {
    175     nativeSetVideoHwAccelerationOptions(nativeFactory, renderEGLContext, renderEGLContext);
    176   }
    177 
    178   /** Set the EGL context used by HW Video encoding and decoding.
    179    *
    180    *
    181    * @param localEGLContext   An instance of javax.microedition.khronos.egl.EGLContext.
    182    *                          Must be the same as used by VideoCapturerAndroid and any local
    183    *                          video renderer.
    184    * @param remoteEGLContext  An instance of javax.microedition.khronos.egl.EGLContext.
    185    *                          Must be the same as used by any remote video renderer.
    186    */
    187   public void setVideoHwAccelerationOptions(Object localEGLContext, Object remoteEGLContext) {
    188     nativeSetVideoHwAccelerationOptions(nativeFactory, localEGLContext, remoteEGLContext);
    189   }
    190 
    191   public void dispose() {
    192     nativeFreeFactory(nativeFactory);
    193     signalingThread = null;
    194     workerThread = null;
    195   }
    196 
    197   public void threadsCallbacks() {
    198     nativeThreadsCallbacks(nativeFactory);
    199   }
    200 
    201   private static void printStackTrace(Thread thread, String threadName) {
    202     if (thread != null) {
    203       StackTraceElement[] stackTraces = thread.getStackTrace();
    204       if (stackTraces.length > 0) {
    205         Logging.d(TAG, threadName + " stacks trace:");
    206         for (StackTraceElement stackTrace : stackTraces) {
    207           Logging.d(TAG, stackTrace.toString());
    208         }
    209       }
    210     }
    211   }
    212 
    213   public static void printStackTraces() {
    214     printStackTrace(workerThread, "Worker thread");
    215     printStackTrace(signalingThread, "Signaling thread");
    216   }
    217 
    218   private static void onWorkerThreadReady() {
    219     workerThread = Thread.currentThread();
    220     Logging.d(TAG, "onWorkerThreadReady");
    221   }
    222 
    223   private static void onSignalingThreadReady() {
    224     signalingThread = Thread.currentThread();
    225     Logging.d(TAG, "onSignalingThreadReady");
    226   }
    227 
    228   private static native long nativeCreatePeerConnectionFactory();
    229 
    230   private static native long nativeCreateObserver(
    231       PeerConnection.Observer observer);
    232 
    233   private static native long nativeCreatePeerConnection(
    234       long nativeFactory, PeerConnection.RTCConfiguration rtcConfig,
    235       MediaConstraints constraints, long nativeObserver);
    236 
    237   private static native long nativeCreateLocalMediaStream(
    238       long nativeFactory, String label);
    239 
    240   private static native long nativeCreateVideoSource(
    241       long nativeFactory, long nativeVideoCapturer,
    242       MediaConstraints constraints);
    243 
    244   private static native long nativeCreateVideoTrack(
    245       long nativeFactory, String id, long nativeVideoSource);
    246 
    247   private static native long nativeCreateAudioSource(
    248       long nativeFactory, MediaConstraints constraints);
    249 
    250   private static native long nativeCreateAudioTrack(
    251       long nativeFactory, String id, long nativeSource);
    252 
    253   private static native boolean nativeStartAecDump(long nativeFactory, int file_descriptor);
    254 
    255   private static native void nativeStopAecDump(long nativeFactory);
    256 
    257   private static native boolean nativeStartRtcEventLog(long nativeFactory, int file_descriptor);
    258 
    259   private static native void nativeStopRtcEventLog(long nativeFactory);
    260 
    261   public native void nativeSetOptions(long nativeFactory, Options options);
    262 
    263   private static native void nativeSetVideoHwAccelerationOptions(
    264       long nativeFactory, Object localEGLContext, Object remoteEGLContext);
    265 
    266   private static native void nativeThreadsCallbacks(long nativeFactory);
    267 
    268   private static native void nativeFreeFactory(long nativeFactory);
    269 }
    270