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