webrtc研究-remb协议分析

来源:互联网 发布:python判断是否是str 编辑:程序博客网 时间:2024/05/24 06:14

分析入口 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就是接受到的带宽???,是不是哪里看漏了

0 0