WebRTC RTP/RTCP 源码分析(三):RTCP 的构造和发送

基于 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<uint16_t>(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<uint16_t>(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
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容