webrtc bandwidth probe

 webrtc可以对网络带宽进行主动探测。视频流的码率相对稳定,因此在带宽探测的时候,因为要向网络中发送多余的数据包,可能会面临着没有新的数据包向外发送的情况。对于这个问题,webrtc采取冗余发送数据包的方式,对带宽进行探测。数据包在发送到网络中,webrtc/modules/rtp_rtcp/source/rtp_sender.cc会将数据包缓存到 packet_history_。在带宽探测是的时候,可以拿出一个与探测包最合适的历史包,冗余发送到网络中。

size_t PacedSender::SendPadding(size_t padding_needed,
                                const PacedPacketInfo& pacing_info) {
  RTC_DCHECK_GT(packet_counter_, 0);
  critsect_.Leave();
  size_t bytes_sent =
      packet_sender_->TimeToSendPadding(padding_needed, pacing_info);//PacketRouter
  critsect_.Enter();

  if (bytes_sent > 0) {
    UpdateBudgetWithBytesSent(bytes_sent);
  }
  return bytes_sent;
}

PacketRouter

size_t PacketRouter::TimeToSendPadding(size_t bytes_to_send,
                                       const PacedPacketInfo& pacing_info) {
  size_t total_bytes_sent = 0;
  rtc::CritScope cs(&modules_crit_);
  // First try on the last rtp module to have sent media. This increases the
  // the chance that any payload based padding will be useful as it will be
  // somewhat distributed over modules according the packet rate, even if it
  // will be more skewed towards the highest bitrate stream. At the very least
  // this prevents sending payload padding on a disabled stream where it's
  // guaranteed not to be useful.
  if (last_send_module_ != nullptr) {
    RTC_DCHECK(std::find(rtp_send_modules_.begin(), rtp_send_modules_.end(),
                         last_send_module_) != rtp_send_modules_.end());
    RTC_DCHECK(last_send_module_->HasBweExtensions());
    total_bytes_sent += last_send_module_->TimeToSendPadding(
        bytes_to_send - total_bytes_sent, pacing_info);
    if (total_bytes_sent >= bytes_to_send) {
      return total_bytes_sent;
    }
  }

  // Rtp modules are ordered by which stream can most benefit from padding.
  for (RtpRtcp* module : rtp_send_modules_) {
    if (module->SendingMedia() && module->HasBweExtensions()) {
      size_t bytes_sent = module->TimeToSendPadding(
          bytes_to_send - total_bytes_sent, pacing_info);//ModuleRtpRtcpImpl
      total_bytes_sent += bytes_sent;
      if (total_bytes_sent >= bytes_to_send)
        break;
    }
  }
  return total_bytes_sent;
}

ModuleRtpRtcpImpl

size_t ModuleRtpRtcpImpl::TimeToSendPadding(
    size_t bytes,
    const PacedPacketInfo& pacing_info) {
  return rtp_sender_->TimeToSendPadding(bytes, pacing_info);//RTPSender
}

RTPSender

size_t RTPSender::TimeToSendPadding(size_t bytes,
                                    const PacedPacketInfo& pacing_info) {
  if (bytes == 0)
    return 0;
  size_t bytes_sent = TrySendRedundantPayloads(bytes, pacing_info);
  if (bytes_sent < bytes)
    bytes_sent += SendPadData(bytes - bytes_sent, pacing_info);
  return bytes_sent;
}
size_t RTPSender::TrySendRedundantPayloads(size_t bytes_to_send,
                                           const PacedPacketInfo& pacing_info) {
  {
    rtc::CritScope lock(&send_critsect_);
    if (!sending_media_)
      return 0;
    if ((rtx_ & kRtxRedundantPayloads) == 0)
      return 0;
  }

  int bytes_left = static_cast(bytes_to_send);
  while (bytes_left > 0) {
    std::unique_ptr packet =
        packet_history_.GetBestFittingPacket(bytes_left);/**if any optimization?**/
    if (!packet)
      break;
    size_t payload_size = packet->payload_size();
    if (!PrepareAndSendPacket(std::move(packet), true, false, pacing_info))
      break;
    bytes_left -= payload_size;
  }
  return bytes_to_send - bytes_left;
}

 最终,拿出一个已经发过的历史数据,再次发送出去,packet_history_.GetBestFittingPacket(bytes_left)。
[1]WebRTC 中的带宽侦测

你可能感兴趣的:(webrtc)