Date: June 9, 2026
Commit: f48df12def0d531a66a3dffcea021fbe0f99dcde
Note: This document was automatically generated by an AI assistant (Gemini) comparing the WebRTC source code with the IETF specification.
This document describes the differences between the WebRTC implementation of SCReAM v2 and the IETF draft draft-johansson-ccwg-rfc8298bis-screamv2-07.
The WebRTC implementation is currently in development and some features are not yet fully implemented.
MinRefWindow (MIN_REF_WND in spec): The spec recommends 3000 bytes (Section 4.2.2). The WebRTC implementation defaults to 1000 bytes in scream_v2_parameters.cc:L21.MaxSegmentSize (MSS in spec): The spec recommends 1000 bytes (Section 4.2.2). The WebRTC implementation defaults to 1280 bytes in scream_v2_parameters.cc:L29.BytesInFlightHeadRoom (BYTES_IN_FLIGHT_HEAD_ROOM in spec): The spec recommends 1.5 (Section 4.2.2). The WebRTC implementation defaults to 1.1 in scream_v2_parameters.cc:L30.bytes_newly_acked and bytes_newly_acked_ce separately and resetting them after window updates as described in the spec (Section 4.1.2), the WebRTC ScreamFeedback struct directly provides acked_not_marked_size (sum of sizes of packets in the feedback that are NOT ECN CE-marked) and num_ce_marked_packets. This simplifies the window update logic in scream_v2.cc.feedback_hold_time_ (the average time feedback is delayed at the receiver before being sent) in scream_v2.cc:L311.congestion_level_ (between 0.0 and 1.0).1.0 / rtts_with_loss_before_backoff (default +1/3). If an RTT is lossless, it steps down by 1.0 / lossless_rtts_before_clear (default -1/2).LossEstimator reports that the connection is congested() (congestion level >= 0.99) OR if queue delay is also detected. See scream_v2.cc:L134-L139.BETA_ECN (default 0.8) (Section 4.2.1.2).BETA_ECN parameter or classic ECN backoff path in scream_v2.cc.l4s_alpha at most once per min(10ms, s_rtt) (Section 4.2.1.3).l4s_alpha_ on every feedback message based on the fraction of marked packets in that specific feedback, without the time interval constraint. See scream_v2.cc:L109-L125.qdelay_dev_norm (Section 4.2.1.4).qdelay_dev_norm with two alternative scaling factors calculated in DelayBasedCongestionControl (delay_based_congestion_control.cc):ref_window_scale_factor_due_to_avg_min_delay (based on queue_delay_min_avg_): Scales growth based on the average minimum queue delay. See delay_based_congestion_control.cc:L122.ref_window_scale_factor_due_to_latency_difference (based on latency_difference_avg_): Scales growth based on the difference between max and min latency in feedback. See delay_based_congestion_control.cc:L131.qdelay_dev_norm terms in the spec.qdelay_avg at most once per min(virtual_rtt, s_rtt).queue_delay_avg_ on every feedback in delay_based_congestion_control.cc:L61-L72.adjust_qdelay_target) to allow SCReAM v2 to compete with aggressive loss-based flows (like TCP Reno/Cubic) by increasing qdelay_target when competing traffic is detected (Section 4.2.1.4.1).queue_delay_target remains static (default 60ms). This is explicitly marked as a TODO in scream_v2_parameters.h:L107.scl_t (scaling factor close to inflection point ref_wnd_i) (Section 4.2.2.1).backoff_scale_factor_close_to_ref_window_i in scream_v2_parameters.cc:L38), meaning the increase/decrease around the inflection point is slower (more cautious) than in the spec.qdelay < qdelay_target * 0.25 (Section 4.2.2.1).!delay_based_congestion_control_.IsQueueDelayDetected(), which translates to queue_delay_avg_ <= queue_delay_target / 2 (default 30ms) (scream_v2.cc:L158).l4s_alpha_ to 0.25 to ensure a rapid reaction if congestion re-occurs (scream_v2.cc:L187). This is not explicitly specified in the spec.ref_window_i) Update Logic:ref_wnd_i is updated to ref_wnd immediately when any congestion event is detected, protected by a simple time-based guard: it cannot be updated more than once every 10 RTTs (Section 4.2.2.1).allow_ref_window_i_update_. It only updates ref_window_i_ when a net decrease in ref_window_ occurs, and then blocks further updates (allow_ref_window_i_update_ = false) until a net increase in ref_window_ has been observed. This ensures ref_window_i_ captures the true peak before a congestion episode and is not dragged down by consecutive back-to-back reductions. See scream_v2.cc:L259-L271.s_rtt / VIRTUAL_RTT (Section 4.2.2.2).rtt_ratio * rtt_ratio) and also includes feedback_hold_time_ in the RTT calculation: (rtt + feedback_hold) / virtual_rtt. This results in a more aggressive reduction of the increase rate for very small RTTs. See scream_v2.cc:L209-L215.target_bitrate reaches TARGET_BITRATE_MAX (Section 4.2.2.2).EnableAlr field trial). The sender enters ALR when the maximum data in flight during the last RTTs is insufficient to fill the reference window (max_allowed_ref_window() < ref_window_). See scream_v2.cc:L68-L70.ref_window_ is strictly prevented from increasing. See scream_v2.cc:L253.1/8 to 1/128 (smoothed_rtt_avg_in_alr_g). This prevents RTT estimates from being corrupted by sparse, potentially delayed feedback samples when traffic is low. See delay_based_congestion_control.cc:L101.ScreamV2::max_data_in_flight() (scream_v2.cc:L286-L297) using the same formula as the spec: ref_window * ref_wnd_overhead (Section 4.3.1).ref_window_scale_factor_due_to_avg_min_delay(true) instead of qdelay_dev_norm to dynamically adjust ref_wnd_overhead between REF_WND_OVERHEAD_MIN (1.5) and REF_WND_OVERHEAD_MAX (3.0).pacing_rate as target_rate_ * pacing_factor (default factor 1.1) in scream_v2.h:L50 and delegates the actual pacing to the standard WebRTC pacer via ScreamNetworkController::MaybeCreatePacerConfig.initial_probing_duration, time_between_periodic_padding, periodic_padding_duration, allow_padding_after_last_congestion_time) defined in scream_v2_parameters.h.rate_adjust_factor (to compensate for media queue buildup) and frame_size_dev (to compensate for varying frame sizes) (Section 4.4).target_rate = scale_target_rate * (ref_window_ / (smoothed_rtt + feedback_hold_time_)) (where scale_target_rate scales down the rate slightly if the window is very small). See scream_v2.cc:L321-L335.queue_delay_drain_threshold, default 5ms) for a prolonged period (queue_delay_drain_period, default 20s), it temporarily halves the target rate for a few RTTs to attempt to drain the queue. If this fails, it resets the queue delay estimate. See scream_v2.cc:L336-L357. This is not explicitly part of Section 4.4 in the spec, but serves as a robust guard against persistent queue build-up.qdelay_min over an RTT, averages it, and triggers a reset and 50% rate reduction if qdelay_min_avg > qdelay_target / 4 (Section 4.5).base_delay_history_ with window length 10) in DelayBasedCongestionControl to track the base delay and compensate for clock drift. The history is updated every 1 minute (base_delay_history_update_interval).UpdateTargetRate (described in Section 4.4 above) acts as the practical trigger for resetting the queue delay estimate if clock drift (or other non-congestion factors) causes the one-way delay to increase permanently.