Some issues about pacing

71 views
Skip to first unread message

teck zhou

unread,
Jun 27, 2024, 6:16:14 AMJun 27
to discuss-webrtc
I've been reading the source code related to pacing, and have encountered a few issues that I haven't been able to figure out as below. Could anyone provide me with a detailed explanation? I would be very grateful.

1) Why insert a small padding packet, then will have a reliable start window for the rate estimation? what does the 'start window' mean?

std::unique_ptr<RtpPacketToSend> PacingController::GetPendingPacket(
    const PacedPacketInfo& pacing_info,
    Timestamp target_send_time,
    Timestamp now) {
  const bool is_probe =
      pacing_info.probe_cluster_id != PacedPacketInfo::kNotAProbe;
  // If first packet in probe, insert a small padding packet so we have a
  // more reliable start window for the rate estimation.
  if (is_probe && pacing_info.probe_cluster_bytes_sent == 0) {
    auto padding = packet_sender_->GeneratePadding(DataSize::Bytes(1));
    // If no RTP modules sending media are registered, we may not get a
    // padding packet back.
    if (!padding.empty()) {
      // We should never get more than one padding packets with a requested
      // size of 1 byte.
      RTC_DCHECK_EQ(padding.size(), 1u);
      return std::move(padding[0]);
    }
  }
...
}

2) Why must sent a 'large enough' packet before set a probe active?

bool BitrateProber::ReadyToSetActiveState(DataSize packet_size) const {
  if (clusters_.empty()) {
    RTC_DCHECK(probing_state_ == ProbingState::kDisabled ||
               probing_state_ == ProbingState::kInactive);
    return false;
  }
  switch (probing_state_) {
    case ProbingState::kDisabled:
    case ProbingState::kActive:
      return false;
    case ProbingState::kInactive:
      // If config_.min_packet_size > 0, a "large enough" packet must be sent
      // first, before a probe can be generated and sent. Otherwise, send the
      // probe asap.
      return packet_size >=
             std::min(RecommendedMinProbeSize(), config_.min_packet_size.Get());
  }
}

3) Why probing sending should use early_execute_margin? What problem is this approach intended to solve?

void TaskQueuePacedSender::MaybeProcessPackets(
    Timestamp scheduled_process_time) {
  ...

  TimeDelta early_execute_margin =
      pacing_controller_.IsProbing()
          ? PacingController::kMaxEarlyProbeProcessing
          : TimeDelta::Zero();

  // Process packets and update stats.
  while (next_send_time <= now + early_execute_margin) {
    pacing_controller_.ProcessPackets();
    next_send_time = pacing_controller_.NextSendTime();
    RTC_DCHECK(next_send_time.IsFinite());

    // Probing state could change. Get margin after process packets.
    early_execute_margin = pacing_controller_.IsProbing()
                               ? PacingController::kMaxEarlyProbeProcessing
                               : TimeDelta::Zero();
  }

...
}
Reply all
Reply to author
Forward
0 new messages