基于 Chromium M69版本
因为当前版本使用发送端带宽预测(SendSideBWE),所以接收端使用 RemoteEstimatorProxy 负责构造 RTCP 包,并通知 TransportFeedbackSenderInterface 发送 RTCP 包。
// /modules/remote_bitrate_estimator/remote_estimator_proxy.cc
// 接收端发送RTCP
void RemoteEstimatorProxy::Process() {
BuildFeedbackPacket(&feedback_packet)
feedback_sender_->SendTransportFeedback(&feedback_packet);
}
// 构造Feedback Packet
bool RemoteEstimatorProxy::BuildFeedbackPacket(
rtcp::TransportFeedback* feedback_packet) {
const int64_t first_sequence = it->first;
feedback_packet->SetMediaSsrc(media_ssrc_);
feedback_packet->SetBase(static_cast(window_start_seq_ & 0xFFFF),
it->second * 1000);
feedback_packet->SetFeedbackSequenceNumber(feedback_sequence_++);
for (; it != packet_arrival_times_.end(); ++it) {
if (!feedback_packet->AddReceivedPacket(
static_cast(it->first & 0xFFFF), it->second * 1000)) {
break;
}
window_start_seq_ = it->first + 1;
}
return true;
}
TransportFeedbackSenderInterface 作为父类,由 PacketRouter 继承,并实现通知 RtpRtcp 发送 RTCP 包的成员函数 SendTransportFeedback()。
// src/modules/pacing/packet_router.cc
// 发送TransportFeedback包
bool PacketRouter::SendTransportFeedback(rtcp::TransportFeedback* packet) {
rtp_module->SendFeedbackPacket(*packet);
}
RtpRtcp 作为父类,由 ModuleRtpRtcpImpl 继承,并实现通知 RTCPSender 发送 RTCP 包的成员函数 SendFeedbackPacket()。
// src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
bool ModuleRtpRtcpImpl::SendFeedbackPacket(
const rtcp::TransportFeedback& packet) {
return rtcp_sender_.SendFeedbackPacket(packet);
}
RTCPSender 负责将 RTCP 包实际交给 Transport 进行传输。
// src/modules/rtp_rtcp/source/rtcp_sender.cc
// 发送TransportFeedback包
bool RTCPSender::SendFeedbackPacket(const rtcp::TransportFeedback& packet) {
transport_->SendRtcp(packet.data(), packet.size());
return packet.BuildExternalBuffer(buffer, max_packet_size, &sender) &&
!sender.send_failure_;
}
Transport 作为父类,由 WebRtcVideoChannel 继承并实现成员函数 SendRtcp(),将 RTCP 包交给 MediaChannel 发送。
// src/media/engine/webrtcvideoengine.cc
bool WebRtcVideoChannel::SendRtcp(const uint8_t* data, size_t len) {
rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen);
return MediaChannel::SendRtcp(&packet, rtc::PacketOptions());
}
MediaChannel 执行 SendRtcp 方法调用 MediaChannel::NetworkInterface 真正发送 RTCP 包
// src/media/base/mediachannel.h
bool SendRtcp(rtc::CopyOnWriteBuffer* packet,
const rtc::PacketOptions& options) {
return DoSendPacket(packet, true, options);
}
bool DoSendPacket(rtc::CopyOnWriteBuffer* packet,
bool rtcp,
const rtc::PacketOptions& options) {
rtc::CritScope cs(&network_interface_crit_);
if (!network_interface_)
return false;
return (!rtcp) ? network_interface_->SendPacket(packet, options)
: network_interface_->SendRtcp(packet, options);
}
MediaChannel::NetworkInterface 作为父类,由 BaseChannel 继承并实现成员函数 SendRtcp()
// src/pc/channel.cc
bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
const rtc::PacketOptions& options) {
return SendPacket(true, packet, options);
}
bool BaseChannel::SendPacket(bool rtcp,
rtc::CopyOnWriteBuffer* packet,
const rtc::PacketOptions& options) {
// ...
// Bon voyage.
return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
: rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
}
//src/pc/rtptransportinternal.h