webrtc研究-remb协议分析

分析入口 webrtc/ideo/vie_remb.cc

void VieRemb::OnReceiveBitrateChanged(const std::vector<uint32_t>& ssrcs,
        uint32_t bitrate) {
        RtpRtcp* sender = nullptr;
        {
            rtc::CritScope lock(&list_crit_);
            // If we already have an estimate, check if the new total estimate is below
            // kSendThresholdPercent of the previous estimate.
            if (last_send_bitrate_ > 0) {
                uint32_t new_remb_bitrate = last_send_bitrate_ - bitrate_ + bitrate;

                if (new_remb_bitrate < kSendThresholdPercent * last_send_bitrate_ / 100) {
                    // The new bitrate estimate is less than kSendThresholdPercent % of the
                    // last report. Send a REMB asap.
                    last_remb_time_ = clock_->TimeInMilliseconds() - kRembSendIntervalMs;
                }
            }
            bitrate_ = bitrate;

            // Calculate total receive bitrate estimate.
            int64_t now = clock_->TimeInMilliseconds();

            if (now - last_remb_time_ < kRembSendIntervalMs) {
                return;
            }
            last_remb_time_ = now;

            if (ssrcs.empty() || receive_modules_.empty()) {
                return;
            }

            // Send a REMB packet.
/*      
            if (!rtcp_sender_.empty()) {
                sender = rtcp_sender_.front();
            }
            else {
                sender = receive_modules_.front();
            }
*/          
            if (!receive_modules_.empty()) {
                sender = receive_modules_.front();
            }
            else {
                sender = rtcp_sender_.front();
            }

            last_send_bitrate_ = bitrate_;
        }

        if (sender) {
            sender->SetREMBData(bitrate_, ssrcs);
        }
    }

}  // namespace webrtc

在改新版webrtc时, 原有的tmmbr/tmmbn改为remb,因为业务需求修改了服务器逻辑,再使用时,发现remb的请求码率一直上不去,分析原因,找个函数作为入口,分析remb的生成计算
调用顺序
remote_bitrate_estimator_single_stream.cc
void RemoteBitrateEstimatorSingleStream::Process()
之后
remote_bitrate_estimator_single_stream.cc
void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t now_ms)
之后
vie_remb.cc
void VieRemb::OnReceiveBitrateChanged(const std::vector& ssrcs, uint32_t bitrate)

好吧,发现是在这条道上产生的,之后发现在
remote_bitrate_estimator_single_stream.cc
void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t now_ms)

void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t now_ms) {
    ......
  double mean_noise_var = sum_var_noise /
      static_cast<double>(overuse_detectors_.size());
  const RateControlInput input(bw_state,
                               incoming_bitrate_.Rate(now_ms),
                               mean_noise_var);
  remote_rate_->Update(&input, now_ms);
  uint32_t target_bitrate = remote_rate_->UpdateBandwidthEstimate(now_ms);
  if (remote_rate_->ValidEstimate()) {
    process_interval_ms_ = remote_rate_->GetFeedbackInterval();
    std::vector<uint32_t> ssrcs;
    GetSsrcs(&ssrcs);
    observer_->OnReceiveBitrateChanged(ssrcs, target_bitrate);
  }
}

码率在此计算?

  const RateControlInput input(bw_state,
                               incoming_bitrate_.Rate(now_ms),
                               mean_noise_var);

进入 incoming_bitrate_.Rate(now_ms)

代码进入,期待解开真相。。。这TMD都是些啥啥啊
rate_statistics.cc

rtc::Optional<uint32_t> RateStatistics::Rate(int64_t now_ms) const {
  // Yeah, this const_cast ain't pretty, but the alternative is to declare most
  // of the members as mutable...
  const_cast<RateStatistics*>(this)->EraseOld(now_ms);

  // If window is a single bucket or there is only one sample in a data set that
  // has not grown to the full window size, treat this as rate unavailable.
  int64_t active_window_size = now_ms - oldest_time_ + 1;
  if (num_samples_ == 0 || active_window_size <= 1 ||
      (num_samples_ <= 1 && active_window_size < current_window_size_ms_)) {
    return rtc::Optional<uint32_t>();
  }

  float scale = scale_ / active_window_size;
  return rtc::Optional<uint32_t>(
      static_cast<uint32_t>(accumulated_count_ * scale + 0.5f));
}

scale_ 是固定的8000
accumulated_count_ * scale + 0.5f
accumulated_count_ *scale_ /(now_ms - oldest_time_ + 1) + 0.5f
如果没有推测错 accumulated_count_ 就是在now_ms - oldest_time_时间接受到的字节数 单位KB,
然后计算出单位时间可以接受的带宽, 单位bit

继续顺藤摸瓜, 验证推测

void RateStatistics::Update(size_t count, int64_t now_ms) {
  if (now_ms < oldest_time_) {
    // Too old data is ignored.
    return;
  }

  EraseOld(now_ms);

  // First ever sample, reset window to start now.
  if (!IsInitialized())
    oldest_time_ = now_ms;

  uint32_t now_offset = static_cast<uint32_t>(now_ms - oldest_time_);
  RTC_DCHECK_LT(now_offset, max_window_size_ms_);
  uint32_t index = oldest_index_ + now_offset;
  if (index >= max_window_size_ms_)
    index -= max_window_size_ms_;
  buckets_[index].sum += count;
  ++buckets_[index].samples;
  accumulated_count_ += count;
  ++num_samples_;
}

看到accumulated_count_ += count;

调用顺序
rtp_stream_receiver.cc
bool RtpStreamReceiver::DeliverRtp(const uint8_t* rtp_packet,
size_t rtp_packet_length,
const PacketTime& packet_time)
之后
congestion_controller.cc
void IncomingPacket(int64_t arrival_time_ms,
size_t payload_size,
const RTPHeader& header)
之后
remote_bitrate_estimator_single_stream.cc
void RemoteBitrateEstimatorSingleStream::IncomingPacket
之后
rate_statistics.cc
void RateStatistics::Update(size_t count, int64_t now_ms)
简单理解 就是接收到数据记个数
???remb就是接受到的带宽???,是不是哪里看漏了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值