1 注意看代码中的注释
//unified plan 会进入到这里
//音频和视频都有各自的 RtpTransceiver
RTCError PeerConnection::UpdateTransceiverChannel(
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
transceiver,
const cricket::ContentInfo& content,
const cricket::ContentGroup* bundle_group) {
RTC_DCHECK(IsUnifiedPlan());
RTC_DCHECK(transceiver);
cricket::ChannelInterface* channel = transceiver->internal()->channel();
if (content.rejected) {
if (channel) {
transceiver->internal()->SetChannel(nullptr);
DestroyChannelInterface(channel);
}
} else {
if (!channel) {
if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) {
channel = CreateVoiceChannel(content.name);
} else {
RTC_DCHECK_EQ(cricket::MEDIA_TYPE_VIDEO, transceiver->media_type());
channel = CreateVideoChannel(content.name);// CreateVideoChannel() 返回的是 cricket::VideoChannel* 指针,但是cricket::VideoChannel*指向的对象中包裹了 VideoMediaChannel的子类,此处就是 cricket::WebRtcVideoChannel
}
if (!channel) {
LOG_AND_RETURN_ERROR(
RTCErrorType::INTERNAL_ERROR,
"Failed to create channel for mid=" + content.name);
}
transceiver->internal()->SetChannel(channel); // 如果是视频,则是将 cricket::VideoChannel* 设置到 RtpTransceiver 中
}
}
return RTCError::OK();
}
void RtpTransceiver::SetChannel(cricket::ChannelInterface* channel) {
// Cannot set a non-null channel on a stopped transceiver.
if (stopped_ && channel) {
return;
}
if (channel) {
RTC_DCHECK_EQ(media_type(), channel->media_type());
}
if (channel_) {
channel_->SignalFirstPacketReceived().disconnect(this);
}
channel_ = channel; // 如果此 RtpTransceiver 是视频相关的,则保存的是 cricket::VideoChannel*, 其指向的对象中包裹了 cricket::VideoMediaChannel 的子类 cricket::WebRtcVideoChannel
if (channel_) {
channel_->SignalFirstPacketReceived().connect(
this, &RtpTransceiver::OnFirstPacketReceived);
}
for (const auto& sender : senders_) {
sender->internal()->SetMediaChannel(channel_ ? channel_->media_channel() // sender->internal() 返回的就是 RtpSenderInternal 的指针,但实际上指向的是 VideoRtpSender
: nullptr); // 如果是视频,channel_ 就是 cricket::VideoChannel*,其内包含 cricket::WebRtcVideoChannel,
}// 也就是说 channel_->media_channel() 返回的 cricket::VideoMediaChannel* 实际上指向的是 cricket::WebRtcVideoChannel,将其设置到 RtpSenderBase 中
for (const auto& receiver : receivers_) {
if (!channel_) {
receiver->internal()->Stop();
}
receiver->internal()->SetMediaChannel(channel_ ? channel_->media_channel() // receiver->internal() 返回的就是 VideoRtpReceiver
: nullptr); // 如果是视频,channel_ 就是 cricket::VideoChannel*,其内包含 cricket::WebRtcVideoChannel,
} // 也就是说 channel_->media_channel() 返回的 cricket::VideoMediaChannel* 实际上指向的是 cricket::WebRtcVideoChannel,将其设置到 VideoRtpReceiver 中
}
void VideoRtpReceiver::SetMediaChannel(cricket::MediaChannel* media_channel) {
RTC_DCHECK(media_channel == nullptr ||
media_channel->media_type() == media_type());
media_channel_ = static_cast<cricket::VideoMediaChannel*>(media_channel);
}