WebRtc VideoRtpSender

来源:互联网 发布:列式数据库 olap 编辑:程序博客网 时间:2024/06/05 14:11

VideoTrack的定义如下:

class VideoTrack : public MediaStreamTrack<VideoTrackInterface>,                   public rtc::VideoSourceBase,                   public ObserverInterface { public:  static rtc::scoped_refptr<VideoTrack> Create(      const std::string& label,      VideoTrackSourceInterface* source);  void AddOrUpdateSink(rtc::VideoSinkInterface<cricket::VideoFrame>* sink,                       const rtc::VideoSinkWants& wants) override;  void RemoveSink(rtc::VideoSinkInterface<cricket::VideoFrame>* sink) override;  VideoTrackSourceInterface* GetSource() const override {    return video_source_.get();  }  bool set_enabled(bool enable) override;  std::string kind() const override; protected:  VideoTrack(const std::string& id, VideoTrackSourceInterface* video_source);  ~VideoTrack(); private:  // Implements ObserverInterface. Observes |video_source_| state.  void OnChanged() override;  rtc::ThreadChecker signaling_thread_checker_;  rtc::ThreadChecker worker_thread_checker_;  rtc::scoped_refptr<VideoTrackSourceInterface> video_source_;};

从它的定义可以看出VideoTrack自己就是VideoSource. 当然实际上它是真正的VideoSource的代理.

跟AudioRtpSender相似, VideoRtpSender是连接VideoTrack和WebRtc Session的纽带. 关键的代码在此:

bool VideoRtpSender::SetTrack(MediaStreamTrackInterface* track) {  TRACE_EVENT0("webrtc", "VideoRtpSender::SetTrack");  if (stopped_) {    LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";    return false;  }  if (track && track->kind() != MediaStreamTrackInterface::kVideoKind) {    LOG(LS_ERROR) << "SetTrack called on video RtpSender with " << track->kind()                  << " track.";    return false;  }  VideoTrackInterface* video_track = static_cast<VideoTrackInterface*>(track);  // Detach from old track.  if (track_) {    track_->UnregisterObserver(this);  }  // Attach to new track.  bool prev_can_send_track = can_send_track();  // Keep a reference to the old track to keep it alive until we call  // SetSource.  rtc::scoped_refptr<VideoTrackInterface> old_track = track_;  track_ = video_track;  if (track_) {    cached_track_enabled_ = track_->enabled();    track_->RegisterObserver(this);  }  // Update video provider.  if (can_send_track()) {    // TODO(deadbeef): If SetTrack is called with a disabled track, and the    // previous track was enabled, this could cause a frame from the new track    // to slip out. Really, what we need is for SetSource and SetVideoSend    // to be combined into one atomic operation, all the way down to    // WebRtcVideoSendStream.    provider_->SetSource(ssrc_, track_);    SetVideoSend();  } else if (prev_can_send_track) {    provider_->SetSource(ssrc_, nullptr);    provider_->SetVideoSend(ssrc_, false, nullptr);  }  return true;}void VideoRtpSender::SetSsrc(uint32_t ssrc) {  TRACE_EVENT0("webrtc", "VideoRtpSender::SetSsrc");  if (stopped_ || ssrc == ssrc_) {    return;  }  // If we are already sending with a particular SSRC, stop sending.  if (can_send_track()) {    provider_->SetSource(ssrc_, nullptr);    provider_->SetVideoSend(ssrc_, false, nullptr);  }  ssrc_ = ssrc;  if (can_send_track()) {    provider_->SetSource(ssrc_, track_);    SetVideoSend();  }}

在这两个函数中, 都调用了 provider_->SetSource. 这里的provider_ 就是WebRtc Session, Session的这个函数 会把Source, 也就是VideoTrack设置成为VideoChannel的Source, 从而完成Video Pipeline的搭建.

1 0