webrtc中rtcp反馈与码率控制模块分析

本文分析了WebRTC发送端如何根据RTCP反馈信息进行码率调整。当RTCP接收报告包到达时,经过处理触发_RtcpBandwidthObserver,计算带宽参数并调用bitratecontrolImpl进行带宽评估。重点讨论了HandleReportBlock中的RTT计算,UpdateMinHistory的变量更新,以及UpdateEstimate在带宽估计中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

webrtc中rtcp反馈与码率控制模块分析

0. 参考文档

1 google congestion control

1. 简介

webrtc的带宽估计分为两部分,一部分为发送端根据rtcp反馈信息进行反馈,另一部分为接收端根据收到的rtp数据进行相应的码率估计[1]。
本文先分析发送端根据rtcp反馈信息进行码率调整的部分代码。

具体计算公式:

2. 代码结构

2.1 类关系

rtp_stream_receiver中有一个继承自抽象类RtpRtcp的ModuleRtpRtcpImpl,ModuleRtpRtcpImpl中有一个rtcp_receiver。当有RTCP包到来时,逐层处理至rtcp_receiver,当包是rtcp receiver report包,则会将包解析,然后在ModuleRtpRtcpImpl中再次调用rtcp_receiver中的TriggerCallbacksFromRTCPPacket函数,触发对应rtcp的一些事件,反馈触发的主要是_cbRtcpBandwidthObserver的观察者(RtcpBandwidthObserverImpl),这个观察者收到对应的report block之后会计算成带宽估计所需要的参数,并调用属主bitratecontrolImpl类对带宽进行估计,这里会调用SendSideBandwidthEstimation中的UpdateReceiverBlock进行实际的带宽评估。

2.2 调用关系图

3. 代码分析

3.1 HandleReportBlock

这个函数中最主要的部分就是RTT的计算,webrtc中对于RTT平滑的因子是一个线性增长的因子。

/* 这个函数根据对应的report block生成了一个新的RTCPReportBlockInformation结构体,
 * 并计算出对应的RTT,多report block在调用点处执行循环。  */
void RTCPReceiver::HandleReportBlock(
    const RTCPUtility::RTCPPacket& rtcpPacket,
    RTCPPacketInformation& rtcpPacketInformation,
    uint32_t remoteSSRC)
    EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
  // This will be called once per report block in the RTCP packet.
  // We filter out all report blocks that are not for us.
  // Each packet has max 31 RR blocks.
  //
  // We can calc RTT if we send a send report and get a report block back.

  // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
  // which the information in this reception report block pertains.

  // Filter out all report blocks that are not for us.
  if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
      registered_ssrcs_.end()) {
    // This block is not for us ignore it.
    return;
  }

  RTCPReportBlockInformation* reportBlock =
      CreateOrGetReportBlockInformation(remoteSSRC,
                                        rtcpPacket.ReportBlockItem.SSRC);
  if (reportBlock == NULL) {
    LOG(LS_WARNING) << "Failed to CreateReportBlockInformation("
        
<think>好的,用户现在想了解WebRTC中TCC的实现原理,并要求用PlantUML绘制时序图。首先,我需要回顾一下之前和用户的对话历史。用户之前询问了TCC和REMB的区别,我已经详细介绍了它们的核心原理、工作流程、适用场景等,现在用户希望深入理解TCC的具体实现。 接下来,我需要明确用户的需求。用户可能是一位开发者,正在学习WebRTC的拥塞控制机制,或者是在实际项目中需要优化网络传输。用户之前已经了解了TCC的基本概念,现在需要更底层的实现细节和时序图来辅助理解。这可能意味着用户希望将理论知识应用于实际开发或问题排查中。 首先,我需要详细解释TCC的实现原理,包括发送端如何标记数据包、接收端如何反馈、发送端如何计算带宽等。这部分需要结构清晰,分步骤说明。然后,绘制PlantUML时序图,展示发送端、接收端以及可能的中继服务器的交互过程。需要注意时序图的准确性和易读性,确保每个步骤对应实现原理中的描述。 在思考过程中,我需要确认TCC的具体实现步骤。例如,发送端在RTP头部添加TransportSequenceNumber扩展,记录发送时间;接收端收集这些信息,生成Transport Feedback报文,并通过RTCP发送回发送端;发送端根据反馈计算延迟梯度,调整码率。这些步骤需要准确无误地呈现。 同时,用户可能希望了解TCC其他机制(如REMB)的不同之处,在解释实现原理时,可以适当对比,但重点应放在TCC本身。另外,用户可能需要知道TCC的优势,比如基于延迟的拥塞控制更及时,适应高动态网络环境,这些也可以在解释中提及。 绘制时序图时,要确保每个环节的顺序正确。例如,发送端发送带有序列号和时间戳的RTP包,接收端接收后记录到达时间,然后生成反馈报文返回,发送端处理反馈并调整码率。需要检查PlantUML语法是否正确,避免出现错误导致无法生成图形。 可能遇到的挑战是如何将技术细节简化,让用户容易理解,同时保持专业性。需要平衡深度和易懂性,避免过于晦涩。此外,需要确保PlantUML代码的正确性,可能需要自己先验证一遍,或者在回答中提示用户如何使用该代码生成图形。 最后,总结部分需要概括TCC的关键点,并强调其优势和适用场景,帮助用户形成整体理解。同时提醒用户TCC需要两端支持,可能在部署时需要注意兼容性。 现在,我需要组织这些思考内容,以结构化的方式呈现给用户,确保逻辑清晰,步骤明确,同时提供可用的PlantUML代码,方便用户直接使用。检查是否有遗漏的步骤或错误的信息,确保回答准确且完整。</think>以下是WebRTC中TCC(Transport-Wide Congestion Control)的实现原理及其PlantUML时序图详解: --- ### **TCC实现原理** #### 核心步骤 1. **RTP包标记** 发送端在**每个RTP包头部**添加`Transport-Wide Sequence Number`扩展(RFC 8888),记录**全局递增的包序列号**和**发送时间戳**。 2. **接收端反馈** 接收端通过RTCP协议中的`Transport Feedback`报文(RFC 4585)反馈以下信息: - 收到的包序列号范围 - 每个包的**到达时间**(微秒级精度) - 丢失的包序列号 3. **发送端计算** 发送端根据反馈数据计算两个关键指标: - **延迟梯度**(Inter-Arrival Delta):相邻包的到达时间差变化 - **传输层延迟增长趋势**(基于Kalman滤波器算法) 通过上述指标判断网络拥塞程度,动态调整发送码率。 --- ### **PlantUML时序图** ```plantuml @startuml participant "发送端" as Sender participant "网络" as Network participant "接收端" as Receiver Sender -> Sender: 为每个RTP包标记\nTransportSequenceNumber和发送时间戳 Sender -> Network: 发送RTP包(Seq=1,2,3...) Network --> Receiver: 转发RTP包(可能丢包/乱序) Receiver -> Receiver: 记录包到达时间\n并检测丢包 Receiver -> Sender: 发送Transport Feedback RTCP报文\n(包含到达时间、丢包信息) Sender -> Sender: 计算延迟梯度\n和网络状态 alt 网络拥塞 Sender -> Sender: 降低发送码率 else 网络空闲 Sender -> Sender: 提高发送码率 end @enduml ``` --- ### **关键算法解析** #### 延迟梯度计算(伪代码) ```python # 接收端记录的包到达时间 packet_arrival_times = { seq1: t1, seq2: t2, ... } # 发送端计算的延迟变化 for i in range(1, n): send_delta = send_time[i] - send_time[i-1] arrive_delta = arrive_time[i] - arrive_time[i-1] delta = arrive_delta - send_delta if delta > threshold: # 判断拥塞 trigger_congestion_control() ``` --- ### **技术优势** 1. **精确的延迟监控** 通过微秒级时间戳差异检测网络拥塞,比传统丢包检测快5-10倍。 2. **跨路径统一控制** 全局序列号机制可同时监控音频、视频、数据等多条流的状态。 3. **公平性保障** 使用`Additive Increase Multiplicative Decrease`(AIMD)算法避免带宽抢占。 --- ### **实际部署注意** 1. **RTP头部扩展协商** 需在SDP中通过`a=extmap`声明TransportSequenceNumber扩展: ```sdp a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 ``` 2. **反馈频率优化** 通常每50ms发送一次Transport Feedback报文,突发场景可缩短至20ms。 --- 该机制已被集成到WebRTC的`SendSideCongestionController`模块中,是当前实时通信场景的最优解之一。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值