Skip to content

feat(interceptor): add GCC sender-side bandwidth estimator#85

Open
nightness wants to merge 1 commit intowebrtc-rs:masterfrom
Brainwires:feat/gcc-bandwidth-estimator
Open

feat(interceptor): add GCC sender-side bandwidth estimator#85
nightness wants to merge 1 commit intowebrtc-rs:masterfrom
Brainwires:feat/gcc-bandwidth-estimator

Conversation

@nightness
Copy link
Copy Markdown

Summary

Add GccInterceptor — a Google Congestion Control (GCC, RFC 8698) bandwidth estimator that uses TWCC feedback to dynamically estimate available send bandwidth.

Key components:

  • TrendlineFilter — sliding window (N=20) OLS linear regression on inter-packet delay gradients; dynamic overuse threshold [6ms, 600ms]
  • AimdRateController — AIMD state machine: 1.08×/sec increase on Normal/Underusing, ×0.85 on Overuse; loss-based adjustment (> 10% loss → decrease)
  • GccHandleArc<Mutex<GccShared>> output channel (no changes to framework's Eout = () contract)
  • GccInterceptorBuilder::new() returns (builder, GccHandle) pair

Chain position (GCC must be inner to TwccSender):

TwccSender → GccInterceptor → SenderReport → NackResponder → NoopInterceptor

Usage:

let (gcc_builder, gcc_handle) = GccInterceptorBuilder::new();
let chain = Registry::new()
    .with(gcc_builder.build())
    .with(TwccSenderBuilder::new().build())
    .build();

// In app polling loop:
if let Some(bps) = gcc_handle.target_bitrate_bps() {
    encoder.set_bitrate(bps);
}

Also includes the JitterBuffer interceptor (receiver-side, RFC 3550 §A.8 adaptive playout delay) as a dependency.

Test plan

  • cargo test -p rtc-interceptor gcc — 8 GCC tests
  • cargo test -p rtc-interceptor jitter_buffer — 6 jitter buffer tests
  • cargo test -p rtc-interceptor — all tests pass

🤖 Generated with Claude Code

Adds a new `GccInterceptor` that processes TWCC feedback packets to
estimate available send bandwidth via trendline delay analysis and AIMD
rate control (RFC 8698 / draft-ietf-rmcat-gcc-02).

- `TrendlineFilter` (trendline.rs): sliding window linear regression of
  accumulated smoothed delay gradient; dynamic threshold adaptation via
  k_up/k_down rules; emits Normal/Overusing/Underusing signal
- `AimdRateController` (rate_controller.rs): 1.08/s multiplicative
  increase on Normal/Underusing; ×0.85 decrease + HOLD on Overuse;
  loss-based adjustment for loss > 10%; bounded [min, max] bps
- `GccInterceptor<P>` (mod.rs): `handle_write` records TWCC send-times
  (ring-buffered by transport-wide seq); `handle_read` intercepts
  `TransportLayerCc` RTCP via `as_any()` downcast, reconstructs
  send/recv pairs, updates trendline + rate controller
- `GccHandle`: `Arc<Mutex<GccShared>>` shared state for application to
  read `target_bitrate_bps` each polling tick without changing the
  interceptor framework's `Eout = ()` contract
- `GccInterceptorBuilder::new()` returns `(builder, handle)` pair
- Chain position: GCC inner to TwccSender so `handle_write` sees
  TWCC-stamped packets
- 18 unit tests (6 trendline, 6 rate_controller, 6 integration)
- All 147 interceptor tests pass; full workspace clean

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant