WebRTC——PeerConnectionFactory.java解析

PeerConnectionFactory一个用来生成PeerConnection的工厂类,WebRTC中最重要的类之一,用来创建peerConnection的类,同时负责初始化全局和底层交互。

//引用so包
static {
    System.loadLibrary("jingle_peerconnection_so");
}
  public static class Options {
    // Keep in sync with webrtc/base/network.h!
    //未知
    static final int ADAPTER_TYPE_UNKNOWN = 0;
    //以太网
    static final int ADAPTER_TYPE_ETHERNET = 1 << 0;
    //WIFI
    static final int ADAPTER_TYPE_WIFI = 1 << 1;
    //移动网络
    static final int ADAPTER_TYPE_CELLULAR = 1 << 2;
    //vpn
    static final int ADAPTER_TYPE_VPN = 1 << 3;
    //回环  
    static final int ADAPTER_TYPE_LOOPBACK = 1 << 4;
    //网络忽略
    public int networkIgnoreMask;
    //解码器
    public boolean disableEncryption;
    //网络监控
    public boolean disableNetworkMonitor;
  }
  //native层初始化全局,如果初始化成功会返回TRUE,否则返回FALSE
  public static native boolean initializeAndroidGlobals(Object context, boolean initializeAudio,
      boolean initializeVideo, boolean videoHwAcceleration);

  // Field trial initialization. Must be called before PeerConnectionFactory
  // is created.
  //一个初始化工作,应该在创建Factory创建之前
  public static native void initializeFieldTrials(String fieldTrialsInitString);

 
  // Internal tracing initialization. Must be called before PeerConnectionFactory is created to
  // prevent racing with tracing code.
  //初始化内部描述
  public static native void initializeInternalTracer();
  // Internal tracing shutdown, called to prevent resource leaks. Must be called after
  // PeerConnectionFactory is gone to prevent races with code performing tracing.

  //关闭内部描述
  public static native void shutdownInternalTracer();

  //打开或关闭内部追踪
  // Start/stop internal capturing of internal tracing.
  public static native boolean startInternalTracingCapture(String tracing_filename);
  public static native void stopInternalTracingCapture();
  //工厂的构造方法,从标签来看,是不建议我们直接使用的
  @Deprecated
  public PeerConnectionFactory() {
    this(null);
  }
  //工厂类的构造方法,调用native层穿进去一组参数
  public PeerConnectionFactory(Options options) {
    nativeFactory = nativeCreatePeerConnectionFactory(options);
    if (nativeFactory == 0) {
      throw new RuntimeException("Failed to initialize PeerConnectionFactory!");
    }
  }
//两种创建PeerConnection的方法,要的参数实质上是一样,返回的也一样,目前不明白区别。。。
 public PeerConnection createPeerConnection(PeerConnection.RTCConfiguration rtcConfig,
      MediaConstraints constraints, PeerConnection.Observer observer) {
    long nativeObserver = nativeCreateObserver(observer);
    if (nativeObserver == 0) {
      return null;
    }
    long nativePeerConnection =
        nativeCreatePeerConnection(nativeFactory, rtcConfig, constraints, nativeObserver);
    if (nativePeerConnection == 0) {
      return null;
    }
    return new PeerConnection(nativePeerConnection, nativeObserver);
  }

  public PeerConnection createPeerConnection(List<PeerConnection.IceServer> iceServers,
      MediaConstraints constraints, PeerConnection.Observer observer) {
    PeerConnection.RTCConfiguration rtcConfig = new PeerConnection.RTCConfiguration(iceServers);
    return createPeerConnection(rtcConfig, constraints, observer);
  }
  //创建本地媒体流
  public MediaStream createLocalMediaStream(String label) {
    return new MediaStream(nativeCreateLocalMediaStream(nativeFactory, label));
  }
  //创建视频资源,调用的都是native层的代码
 public VideoSource createVideoSource(VideoCapturer capturer) {
    final EglBase.Context eglContext =
        localEglbase == null ? null : localEglbase.getEglBaseContext();
    long nativeAndroidVideoTrackSource =
        nativeCreateVideoSource(nativeFactory, eglContext, capturer.isScreencast());
    VideoCapturer.CapturerObserver capturerObserver =
        new VideoCapturer.AndroidVideoTrackSourceObserver(nativeAndroidVideoTrackSource);
    nativeInitializeVideoCapturer(
        nativeFactory, capturer, nativeAndroidVideoTrackSource, capturerObserver);
    return new VideoSource(nativeAndroidVideoTrackSource);
  }
//创建音频资源
public AudioSource createAudioSource(MediaConstraints constraints) {
    return new AudioSource(nativeCreateAudioSource(nativeFactory, constraints));
  }
//创建视频足记与音频足记
public VideoTrack createVideoTrack(String id, VideoSource source) {
    return new VideoTrack(nativeCreateVideoTrack(nativeFactory, id, source.nativeSource));
  }

public AudioTrack createAudioTrack(String id, AudioSource source) {
    return new AudioTrack(nativeCreateAudioTrack(nativeFactory, id, source.nativeSource));
  }
  // Starts recording an AEC dump. Ownership of the file is transfered to the
  // native code. If an AEC dump is already in progress, it will be stopped and
  // a new one will start using the provided file.
  //使用一定文件空间转码
  public boolean startAecDump(int file_descriptor, int filesize_limit_bytes) {
    return nativeStartAecDump(nativeFactory, file_descriptor, filesize_limit_bytes);
  }

  // Stops recording an AEC dump. If no AEC dump is currently being recorded,
  // this call will have no effect.
  //停止转码
  public void stopAecDump() {
    nativeStopAecDump(nativeFactory);
  }
//设置状态,对应无参数的构造方法,同样不建议被使用
@Deprecated
  public void setOptions(Options options) {
    nativeSetOptions(nativeFactory, options);
  }
  
  public void setVideoHwAccelerationOptions(
      EglBase.Context localEglContext, EglBase.Context remoteEglContext) {
    if (localEglbase != null) {
      Logging.w(TAG, "Egl context already set.");
      localEglbase.release();
    }
    if (remoteEglbase != null) {
      Logging.w(TAG, "Egl context already set.");
      remoteEglbase.release();
    }
    localEglbase = EglBase.create(localEglContext);
    remoteEglbase = EglBase.create(remoteEglContext);
    nativeSetVideoHwAccelerationOptions(
        nativeFactory, localEglbase.getEglBaseContext(), remoteEglbase.getEglBaseContext());
  }
  //处理掉,关闭的
 public void dispose() {
    nativeFreeFactory(nativeFactory);
    networkThread = null;
    workerThread = null;
    signalingThread = null;
    if (localEglbase != null)
      localEglbase.release();
    if (remoteEglbase != null)
      remoteEglbase.release();
  }
//回调线程
public void threadsCallbacks() {
    nativeThreadsCallbacks(nativeFactory);
  }
  //输出现在的调用帧
  private static void printStackTrace(Thread thread, String threadName) {
    if (thread != null) {
      StackTraceElement[] stackTraces = thread.getStackTrace();
      if (stackTraces.length > 0) {
        Logging.d(TAG, threadName + " stacks trace:");
        for (StackTraceElement stackTrace : stackTraces) {
          Logging.d(TAG, stackTrace.toString());
        }
      }
    }
  }

  public static void printStackTraces() {
    printStackTrace(networkThread, "Network thread");
    printStackTrace(workerThread, "Worker thread");
    printStackTrace(signalingThread, "Signaling thread");
  }
  //当线程准备完毕
  private static void onNetworkThreadReady() {
    networkThread = Thread.currentThread();
    Logging.d(TAG, "onNetworkThreadReady");
  }

  private static void onWorkerThreadReady() {
    workerThread = Thread.currentThread();
    Logging.d(TAG, "onWorkerThreadReady");
  }

  private static void onSignalingThreadReady() {
    signalingThread = Thread.currentThread();
    Logging.d(TAG, "onSignalingThreadReady");
  }
  //native层代码

  //创建peerConnectionFactory
  private static native long nativeCreatePeerConnectionFactory(Options options);

  //创建回调的listener
  private static native long nativeCreateObserver(PeerConnection.Observer observer);

  //创建peerConnection
  private static native long nativeCreatePeerConnection(long nativeFactory,
      PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, long nativeObserver);

  //创建本地的媒体流
  private static native long nativeCreateLocalMediaStream(long nativeFactory, String label);

  //创建音频资源
  private static native long nativeCreateVideoSource(
      long nativeFactory, EglBase.Context eglContext, boolean is_screencast);

  //初始化视频的资源
  private static native void nativeInitializeVideoCapturer(long native_factory,
      VideoCapturer j_video_capturer, long native_source,
      VideoCapturer.CapturerObserver j_frame_observer);
  
  //创建视频足记
  private static native long nativeCreateVideoTrack(
      long nativeFactory, String id, long nativeVideoSource);
  
  //创建音频资源
  private static native long nativeCreateAudioSource(
      long nativeFactory, MediaConstraints constraints);
  
  //创建音频足记
  private static native long nativeCreateAudioTrack(
      long nativeFactory, String id, long nativeSource);

  //开启ace转码
  private static native boolean nativeStartAecDump(
      long nativeFactory, int file_descriptor, int filesize_limit_bytes);

  //关闭ace转码
  private static native void nativeStopAecDump(long nativeFactory);

  //设置配置
  @Deprecated public native void nativeSetOptions(long nativeFactory, Options options);

  //设置怎么样的转码方式,加速的方式
  private static native void nativeSetVideoHwAccelerationOptions(
      long nativeFactory, Object localEGLContext, Object remoteEGLContext);
  
  //不同线程的回调
  private static native void nativeThreadsCallbacks(long nativeFactory);

  //释放factory的控件
  private static native void nativeFreeFactory(long nativeFactory);
  //各种编码格式的相互转换
  public static native void nativeARGBToNV21(byte[] src, int width, int height, byte[] dst);
  
  public static native void nativeRGBAToNV21(byte[] src, int width, int height, byte[] dst);
  
  public static native void nativeNV21ToARGB(byte[] src, int width, int height, byte[] dst);
  
  public static native void nativeNV12ToNV21(byte[] src, int width, int height);

  public static native void nativeI420ToARGB(byte[] src, int width, int height, byte[] dst);

  public static native void nativeI420ToNV21(byte[] src, int width, int height, byte[] dst);

以上便是rtc中的peerConnection类~
以上便是博主的一点点的小见解,欢迎大家和我讨论~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,612评论 5 471
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,345评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,625评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,022评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,974评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,227评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,688评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,358评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,490评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,402评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,446评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,721评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,802评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,013评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,504评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,080评论 2 341

推荐阅读更多精彩内容