RR报文解析(二) fraction lost

xiaoxiao2021-02-27  262

先附上RR报文的图:

这节我们看下RR报文的fraction lost字段,它占8位,RFC_3550中对他的解释为: The sender of the receiver report estimates the fraction of the RTP data packets from source SSRC_n that it assumes to be lost since it sent the previous SR or RR packet.

翻译过来大概是:RR报文的发送者估计的,自从上一次发送SR或RR报文后,它从SSRC_n 源端接收到的RTP包的丢包率。

我们注意到它占8位,不难猜出,真实的丢包率是个小数,它由fraction lost字段除以256得到。

下面我们看下,计算平均丢包率的代码:

void RtcpBandwidthObserverImpl::OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks, int64_t rtt, int64_t now_ms) override { if (report_blocks.empty()) return; int fraction_lost_aggregate = 0; int total_number_of_packets = 0; // Compute the a weighted average of the fraction loss from all report // blocks. for (ReportBlockList::const_iterator it = report_blocks.begin(); it != report_blocks.end(); ++it) { std::map<uint32_t, uint32_t>::iterator seq_num_it = ssrc_to_last_received_extended_high_seq_num_.find(it->sourceSSRC); int number_of_packets = 0; if (seq_num_it != ssrc_to_last_received_extended_high_seq_num_.end()) number_of_packets = it->extendedHighSeqNum - //当前接收到的rtp最高序列号减上一次的最高序列号,得到应该发送的rtp的数量 seq_num_it->second; fraction_lost_aggregate += number_of_packets * it->fractionLost; total_number_of_packets += number_of_packets; // Update last received for this SSRC. ssrc_to_last_received_extended_high_seq_num_[it->sourceSSRC] = it->extendedHighSeqNum; } if (total_number_of_packets == 0) fraction_lost_aggregate = 0; else fraction_lost_aggregate = (fraction_lost_aggregate + //得到的fraction_lost_aggregate其实是平均丢帧率*256, 为何要加上total_number_of_packets / 2,至今不是很明白 total_number_of_packets / 2) / total_number_of_packets; if (fraction_lost_aggregate > 255) return; owner_->OnReceivedRtcpReceiverReport(fraction_lost_aggregate, rtt, total_number_of_packets, now_ms); }

为了理解,假设先后收到了3个RR报文,每次接收到的number_of_packets为n1, n2, n3, 每次的fractionLost为f1, f2, f3, 则最后计算出来的fraction_lost_aggregate 为: (n1*f1 + n2*f2 + n3*f3 + (n1 + n2 + n3) / 2) / (n1 + n2 + n3).

其实我不太明白为什么要加上(n1 + n2 + n3) / 2, 正常情况下应该是: (n1*f1 + n2*f2 + n3*f3) / (n1 + n2 + n3).

可能是为了防止结果被四舍五入吧。

最后结论,可以认为fraction_lost_aggregate 为平均丢包率 * 256, 因为丢包率小于1,所以结果不能大于256.

然后,还没完,得到fraction_lost_aggregate 后,它调用了owner_->OnReceivedRtcpReceiverReport(fraction_lost_aggregate, rtt, total_number_of_packets, now_ms);

void BitrateControllerImpl::OnReceivedRtcpReceiverReport( uint8_t fraction_loss, int64_t rtt, int number_of_packets, int64_t now_ms) { { rtc::CritScope cs(&critsect_); bandwidth_estimation_.UpdateReceiverBlock(fraction_loss, rtt, number_of_packets, now_ms); } MaybeTriggerOnNetworkChanged(); }

bandwidth_estimation_是SendSideBandwidthEstimation类,它是估计发送码率的重要类,看下UpdateReceiverBlock函数:

void SendSideBandwidthEstimation::UpdateReceiverBlock(uint8_t fraction_loss, int64_t rtt, int number_of_packets, int64_t now_ms) { if (first_report_time_ms_ == -1) first_report_time_ms_ = now_ms; // Update RTT. last_round_trip_time_ms_ = rtt; // Check sequence number diff and weight loss report if (number_of_packets > 0) { // Calculate number of lost packets. const int num_lost_packets_Q8 = fraction_loss * number_of_packets; // Accumulate reports. lost_packets_since_last_loss_update_Q8_ += num_lost_packets_Q8; expected_packets_since_last_loss_update_ += number_of_packets; // Don't generate a loss rate until it can be based on enough packets. if (expected_packets_since_last_loss_update_ < kLimitNumPackets) return; has_decreased_since_last_fraction_loss_ = false; last_fraction_loss_ = lost_packets_since_last_loss_update_Q8_ / //主要在这里,得出last_fraction_loss_ expected_packets_since_last_loss_update_; // Reset accumulators. lost_packets_since_last_loss_update_Q8_ = 0; expected_packets_since_last_loss_update_ = 0; } time_last_receiver_block_ms_ = now_ms; UpdateEstimate(now_ms); //估算码率!!! UpdateUmaStats(now_ms, rtt, (fraction_loss * number_of_packets) >> 8); }
转载请注明原文地址: https://www.6miu.com/read-7218.html

最新回复(0)