WebRTC-PeerConnectionFactory.java解析

PeerConnectionFactory一個(gè)用來生成PeerConnection的工廠類值骇,WebRTC中最重要的類之一,用來創(chuàng)建peerConnection的類鞭呕,同時(shí)負(fù)責(zé)初始化全局和底層交互。

加載so庫

    static {
        try {
            System.loadLibrary("jingle_peerconnection_so");
            nativeLibLoaded = true;
        } catch (UnsatisfiedLinkError var1) {
            nativeLibLoaded = false;
        }

    }

網(wǎng)絡(luò)接口相關(guān)參數(shù)

public static class Options {
        //未知
        static final int ADAPTER_TYPE_UNKNOWN = 0;
        //以太網(wǎng)
        static final int ADAPTER_TYPE_ETHERNET = 1;
        //WIFI
        static final int ADAPTER_TYPE_WIFI = 2;
        //移動(dòng)網(wǎng)絡(luò)
        static final int ADAPTER_TYPE_CELLULAR = 4;
        //vpn
        static final int ADAPTER_TYPE_VPN = 8;
        //回環(huán) 
        static final int ADAPTER_TYPE_LOOPBACK = 16;
        
         //網(wǎng)絡(luò)忽略宛官,與PeerConnectionParameters.loopback有關(guān)
         public int networkIgnoreMask;
         //解碼器
         public boolean disableEncryption;
        //網(wǎng)絡(luò)監(jiān)控
        public boolean disableNetworkMonitor;

        public Options() {
        }
    }

初始化PeerConnectionFactory

//native層初始化全局葫松,如果初始化成功會(huì)返回TRUE,否則返回FALSE
/*
*Context:簡(jiǎn)單的ApplicationContext瓦糕,或者其他Context相關(guān)的上下文
*videoHwAcceleration:是否啟用硬件加速
*/
public static void initializeAndroidGlobals(Context context, boolean videoHwAcceleration) {
        ContextUtils.initialize(context);
        nativeInitializeAndroidGlobals(context, videoHwAcceleration);
    }

//一個(gè)初始化工作,應(yīng)該在創(chuàng)建Factory創(chuàng)建之前进宝,用來初始化音視頻軌
//fieldTrialsInitString:音視頻軌的描述
public static native void initializeFieldTrials(String fieldTrialsInitString);

//初始化內(nèi)部描述
public static native void initializeInternalTracer();
//關(guān)閉內(nèi)部描述
public static native void shutdownInternalTracer();

//打開或關(guān)閉內(nèi)部追蹤刻坊,創(chuàng)建一個(gè)log文件,與PeerConnectionParameters.tracing有關(guān)
public static native boolean startInternalTracingCapture(String var0);
public static native void stopInternalTracingCapture();

工廠構(gòu)造方法

    /** @deprecated 看來已經(jīng)不建議使用*/
    @Deprecated
    public PeerConnectionFactory() {
        this((PeerConnectionFactory.Options)null);
    }
    
    //很明顯党晋,調(diào)用了下面的構(gòu)造方法
    public PeerConnectionFactory(PeerConnectionFactory.Options options) {
        this(options, (VideoEncoderFactory)null, (VideoDecoderFactory)null);
    }
    //調(diào)用native層傳進(jìn)去一組參數(shù)
   /**
   * 
   * @param options    網(wǎng)絡(luò)接口相關(guān)參數(shù)
   * @param encoderFactory    視頻編碼器接口谭胚,創(chuàng)建視頻編碼器及格式
   * @param decoderFactory    視頻解碼器接口,創(chuàng)建視頻解碼器
   */
    public PeerConnectionFactory(PeerConnectionFactory.Options options, VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory) {
        this.nativeFactory = nativeCreatePeerConnectionFactory(options, encoderFactory, decoderFactory);
        if (this.nativeFactory == 0L) {
            throw new RuntimeException("Failed to initialize PeerConnectionFactory!");
        }
    }

創(chuàng)建PeerConnection

  /**
   * 
   * @param rtcConfig    WebRTC通信最主要的配置未玻,主要是配置IceServer信息
   * @param constraints    媒體約束類
   * @param observer    ICE和音視頻流變化時(shí)的回調(diào)接口
   */
  public PeerConnection createPeerConnection(PeerConnection.RTCConfiguration rtcConfig,
      MediaConstraints constraints, PeerConnection.Observer observer) {
        long nativeObserver = nativeCreateObserver(observer);
        if (nativeObserver == 0L) {
            return null;
        } else {
            long nativePeerConnection = nativeCreatePeerConnection(this.nativeFactory, rtcConfig, constraints, nativeObserver);
            return nativePeerConnection == 0L ? null : new PeerConnection(nativePeerConnection, nativeObserver);
        }
    }
  /**
   * 
   * @param rtcConfig    IceServer信息
   * @param constraints    媒體約束類
   * @param observer    ICE和音視頻流變化時(shí)的回調(diào)接口
   */
    public PeerConnection createPeerConnection(List<PeerConnection.IceServer> iceServers,
      MediaConstraints constraints, PeerConnection.Observer observer) {
        RTCConfiguration rtcConfig = new RTCConfiguration(iceServers);
        return this.createPeerConnection(rtcConfig, constraints, observer);
    }

創(chuàng)建本地媒體流

public MediaStream createLocalMediaStream(String label) {
        return new MediaStream(nativeCreateLocalMediaStream(this.nativeFactory, label));
    }

創(chuàng)建本地視頻源灾而,調(diào)用的都是native層的代碼

public VideoSource createVideoSource(VideoCapturer capturer) {
        org.webrtc.EglBase.Context eglContext = this.localEglbase == null ? null : this.localEglbase.getEglBaseContext();
        SurfaceTextureHelper surfaceTextureHelper = SurfaceTextureHelper.create("VideoCapturerThread", eglContext);
        long nativeAndroidVideoTrackSource = nativeCreateVideoSource(this.nativeFactory, surfaceTextureHelper, capturer.isScreencast());
        CapturerObserver capturerObserver = new AndroidVideoTrackSourceObserver(nativeAndroidVideoTrackSource);
        capturer.initialize(surfaceTextureHelper, ContextUtils.getApplicationContext(), capturerObserver);
        return new VideoSource(nativeAndroidVideoTrackSource);
    }

創(chuàng)建視頻軌

public VideoTrack createVideoTrack(String id, VideoSource source) {
        return new VideoTrack(nativeCreateVideoTrack(this.nativeFactory, id, source.nativeSource));
    }

創(chuàng)建本地音頻流

    public AudioSource createAudioSource(MediaConstraints constraints) {
        return new AudioSource(nativeCreateAudioSource(this.nativeFactory, constraints));
    }

創(chuàng)建音頻軌

    public AudioTrack createAudioTrack(String id, AudioSource source) {
        return new AudioTrack(nativeCreateAudioTrack(this.nativeFactory, id, source.nativeSource));
    }

Aec轉(zhuǎn)碼

  // 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.
  //使用一定文件空間轉(zhuǎn)碼
  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.
  //停止轉(zhuǎn)碼
  public void stopAecDump() {
    nativeStopAecDump(nativeFactory);
  }

設(shè)置網(wǎng)絡(luò)狀態(tài),

    /** @deprecated對(duì)應(yīng)無參數(shù)的構(gòu)造方法扳剿,同樣不建議被使用 */
    @Deprecated
    public void setOptions(PeerConnectionFactory.Options options) {
        this.nativeSetOptions(this.nativeFactory, options);
    }

設(shè)置視頻硬件加速參數(shù)

    public void setVideoHwAccelerationOptions(org.webrtc.EglBase.Context localEglContext, org.webrtc.EglBase.Context remoteEglContext) {
        if (this.localEglbase != null) {
            Logging.w("PeerConnectionFactory", "Egl context already set.");
            this.localEglbase.release();
        }

        if (this.remoteEglbase != null) {
            Logging.w("PeerConnectionFactory", "Egl context already set.");
            this.remoteEglbase.release();
        }

        this.localEglbase = EglBase.create(localEglContext);
        this.remoteEglbase = EglBase.create(remoteEglContext);
        nativeSetVideoHwAccelerationOptions(this.nativeFactory, this.localEglbase.getEglBaseContext(), this.remoteEglbase.getEglBaseContext());
    }

釋放資源旁趟,回收PeerConnectionFactory

    public void dispose() {
        nativeFreeFactory(this.nativeFactory);
        networkThread = null;
        workerThread = null;
        signalingThread = null;
        if (this.localEglbase != null) {
            this.localEglbase.release();
        }

        if (this.remoteEglbase != null) {
            this.remoteEglbase.release();
        }

    }

回調(diào)線程

public void threadsCallbacks() {
        nativeThreadsCallbacks(this.nativeFactory);
    }

輸出現(xiàn)在的調(diào)用幀

    private static void printStackTrace(Thread thread, String threadName) {
        if (thread != null) {
            StackTraceElement[] stackTraces = thread.getStackTrace();
            if (stackTraces.length > 0) {
                Logging.d("PeerConnectionFactory", threadName + " stacks trace:");
                StackTraceElement[] var3 = stackTraces;
                int var4 = stackTraces.length;

                for(int var5 = 0; var5 < var4; ++var5) {
                    StackTraceElement stackTrace = var3[var5];
                    Logging.d("PeerConnectionFactory", stackTrace.toString());
                }
            }
        }

    }
    public static void printStackTraces() {
        printStackTrace(networkThread, "Network thread");
        printStackTrace(workerThread, "Worker thread");
        printStackTrace(signalingThread, "Signaling thread");
    }

當(dāng)線程準(zhǔn)備完畢

    private static void onNetworkThreadReady() {
        networkThread = Thread.currentThread();
        Logging.d("PeerConnectionFactory", "onNetworkThreadReady");
    }

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

    private static void onSignalingThreadReady() {
        signalingThread = Thread.currentThread();
        Logging.d("PeerConnectionFactory", "onSignalingThreadReady");
    }

native層代碼

//創(chuàng)建peerConnectionFactory
  private static native long nativeCreatePeerConnectionFactory(Options options);

  //創(chuàng)建回調(diào)的listener
  private static native long nativeCreateObserver(PeerConnection.Observer observer);

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

  //創(chuàng)建本地的媒體流
  private static native long nativeCreateLocalMediaStream(long nativeFactory, String label);

  //創(chuàng)建音頻資源
  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);
  
  //創(chuàng)建視頻足記
  private static native long nativeCreateVideoTrack(
      long nativeFactory, String id, long nativeVideoSource);
  
  //創(chuàng)建音頻資源
  private static native long nativeCreateAudioSource(
      long nativeFactory, MediaConstraints constraints);
  
  //創(chuàng)建音頻足記
  private static native long nativeCreateAudioTrack(
      long nativeFactory, String id, long nativeSource);

  //開啟ace轉(zhuǎn)碼
  private static native boolean nativeStartAecDump(
      long nativeFactory, int file_descriptor, int filesize_limit_bytes);

  //關(guān)閉ace轉(zhuǎn)碼
  private static native void nativeStopAecDump(long nativeFactory);

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

  //設(shè)置怎么樣的轉(zhuǎn)碼方式,加速的方式
  private static native void nativeSetVideoHwAccelerationOptions(
      long nativeFactory, Object localEGLContext, Object remoteEGLContext);
  
  //不同線程的回調(diào)
  private static native void nativeThreadsCallbacks(long nativeFactory);

  //釋放factory的控件
  private static native void nativeFreeFactory(long nativeFactory);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末庇绽,一起剝皮案震驚了整個(gè)濱河市锡搜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瞧掺,老刑警劉巖耕餐,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異辟狈,居然都是意外死亡肠缔,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門哼转,熙熙樓的掌柜王于貴愁眉苦臉地迎上來明未,“玉大人,你說我怎么就攤上這事壹蔓√送祝” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵佣蓉,是天一觀的道長(zhǎng)披摄。 經(jīng)常有香客問我,道長(zhǎng)偏螺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任匆光,我火速辦了婚禮套像,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘终息。我一直安慰自己夺巩,他們只是感情好贞让,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著柳譬,像睡著了一般喳张。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上美澳,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天销部,我揣著相機(jī)與錄音,去河邊找鬼制跟。 笑死舅桩,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的雨膨。 我是一名探鬼主播擂涛,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼聊记!你這毒婦竟也來了撒妈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤排监,失蹤者是張志新(化名)和其女友劉穎狰右,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體社露,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挟阻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了峭弟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片附鸽。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖瞒瘸,靈堂內(nèi)的尸體忽然破棺而出坷备,到底是詐尸還是另有隱情,我是刑警寧澤情臭,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布省撑,位于F島的核電站,受9級(jí)特大地震影響俯在,放射性物質(zhì)發(fā)生泄漏竟秫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一跷乐、第九天 我趴在偏房一處隱蔽的房頂上張望肥败。 院中可真熱鬧,春花似錦、人聲如沸馒稍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纽谒。三九已至证膨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鼓黔,已是汗流浹背央勒。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留请祖,地道東北人订歪。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像肆捕,于是被迫代替她去往敵國和親刷晋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容