WebRtc VideoRtpSender

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的搭建.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值