webrtc proxy 分析

webrtc proxy 分析

在webrtc中,许多重要的对象实际上都是“代理对象”,如PeerConnection, PeerConnectionFactory,等等,可以看下PeerConnectionFactory的源代码:

rtc::scoped_refptr<PeerConnectionFactoryInterface>
CreatePeerConnectionFactory() {
  rtc::scoped_refptr<PeerConnectionFactory> pc_factory(    
      new rtc::RefCountedObject<PeerConnectionFactory>()); 

  RTC_CHECK(rtc::Thread::Current() == pc_factory->signaling_thread());

  if (!pc_factory->Initialize()) {  
    return nullptr;
  }
  return PeerConnectionFactoryProxy::Create(pc_factory->signaling_thread(),pc_factory);   
}

从代码可以看出,创建PeerConnectionFactory实际上返回的是PeerConnectionFactoryProxy对象。那这么做有什么用呢?从PeerConnectionFactoryProxy::Create(pc_factory→signaling_thread(), pc_factory); 中可以看到,Create的还有一个参数是pc_factory→signaling_thread(),猜一下也知道,这是为了解决多线程问题的。其实,他是为了保证所有的proxy对象的操作都在singaling线程中,当在另一个线程调用了proxy对象的方法时,proxy对象会将该方法的操作包装成一个message,发送给singaling线程,然后阻塞等待singaling线程中执行完成。

下面可以看一下它的源码是如何实现的,为了简单起见,使用MediaStream为例说明:

rtc::scoped_refptr<MediaStreamInterface>
PeerConnectionFactory::CreateLocalMediaStream(const std::string& label) {
  RTC_DCHECK(signaling_thread_->IsCurrent());
  return MediaStreamProxy::Create(signaling_thread_,
                                  MediaStream::Create(label));
}

MediaStreamProxy实际上是由一个宏生成的,如下:

BEGIN_SIGNALING_PROXY_MAP(MediaStream)
  PROXY_CONSTMETHOD0(std::string, label)
  PROXY_METHOD0(AudioTrackVector, GetAudioTracks)
  PROXY_METHOD0(VideoTrackVector, GetVideoTracks)
  PROXY_METHOD1(rtc::scoped_refptr<AudioTrackInterface>,
                FindAudioTrack, const std::string&)
  PROXY_METHOD1(rtc::scoped_refptr<VideoTrackInterface>,
                FindVideoTrack, const std::string&)
  PROXY_METHOD1(bool, AddTrack, AudioTrackInterface*)
  PROXY_METHOD1(bool, AddTrack, VideoTrackInterface*)
  PROXY_METHOD1(bool, RemoveTrack, AudioTrackInterface*)
  PROXY_METHOD1(bool, RemoveTrack, VideoTrackInterface*)
  PROXY_METHOD1(void, RegisterObserver, ObserverInterface*)
  PROXY_METHOD1(void, UnregisterObserver, ObserverInterface*)
END_SIGNALING_PROXY()
}

把这些宏都展开,如下(为避免太长砍掉了很多函数):

class MediaStreamProxy : public MediaStreamInterface {                                  \
protected:                                                             
    typedef MediaStreamInterface C;  

    MediaStreamProxy(rtc::Thread* signaling_thread, C* c)                      
      : signaling_thread_(signaling_thread), c_(c) {}                    
    ~MediaStreamProxy() {                                                        
      MethodCall0<MediaStreamProxy, void> call(                                 
        this, &MediaStreamProxy::Release_s);                                 
        call.Marshal(signaling_thread_);                                   
    }                                                                    

public:                                                              
    static rtc::scoped_refptr<C> Create(rtc::Thread* signaling_thread, C* c) { 
        return new rtc::RefCountedObject<MediaStreamProxy>(                         
            signaling_thread, c);                                         
    }

    std::string label() const override {                         
        ConstMethodCall0<C, std::string> call(c_.get(), &C::label); 
        return call.Marshal(signaling_thread_);            
    }

    AudioTrackVector GetAudioTracks() override {                           
        MethodCall0<C, AudioTrackVector> call(c_.get(), &C::GetAudioTracks); 
        return call.Marshal(signaling_thread_);       
    }

private:
    void Release_s() {
        c_ = NULL;
    }
    mutable rtc::Thread* signaling_thread_;
    rtc::scoped_refptr<C> c_;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值