Commit Graph

1102 Commits

Author SHA1 Message Date
Raja Subramanian 4872f2051d Return write count from WriteRTP. (#4059)
* Log write count atomic.

* Return write count from WriteRTP.

Apologies for the frequent changes on this. With relays, the down track
could write to several targets. So, use count to have an accurate
indication of how may subscribers were written to.
2025-11-06 13:29:21 +05:30
Raja Subramanian d0ba46b460 Log write count atomic. (#4057) 2025-11-06 13:00:08 +05:30
Raja Subramanian ae5fb7e882 Add packet to forwarding stats only if packet is forwarded. (#4056)
Packets not being forwarded were getting included in forwarding stats
calculation and skewing the measurement towards a smaller number.

The latency measurement does not include the batch IO of packets on
send. With a 2ms batching, that will add an average latency of 1ms.
2025-11-06 12:31:49 +05:30
cnderrauber c264b504c4 Don't warn 0 payload type for PCMU (#4039) 2025-10-28 23:11:51 +08:00
Raja Subramanian 32fc35254e Broadcast cond var on RTX write. (#4038)
* Broadcast cond var on RTX write.

High forwarding latency logs all show high queuing delay so far. From
code inspection, RTX writes were not signaling the cond var. Not sure if
that is the reason, but adding a signal there for further tests.

* Remove return values from writeRTX as they are not used
2025-10-28 11:27:02 +05:30
Raja Subramanian 061eb8b4e8 AddDownTrack to regressed codec after restarting forwarder. (#4037)
Without that the new codec was skipping through with old selector and
not working correctly.
2025-10-27 20:14:33 +05:30
Raja Subramanian ab906d710c Prevent leakage of previous codec after codec regression. (#4035)
* Prevent leakage of previous codec after codec regression.

In the window between forwarder restart and determining codec, the old
codec packet could leak through. Prevent tha by doing the restart and
codec determination atomically on a codec regression.

* tidy

* use locked function
2025-10-27 17:40:39 +05:30
Raja Subramanian 79b03f97a2 Log queueing latency when encountering high forwarding latency (#4034) 2025-10-27 15:27:03 +05:30
Raja Subramanian 29117b1422 set max layer in allocation (#4033) 2025-10-26 17:51:35 +05:30
Raja Subramanian 34e16a8709 Check more conditions for opportunistic alloc. (#4031) 2025-10-26 14:03:26 +05:30
Raja Subramanian 81fbd3551a Use the optimal allocation function for opportunistic allocation. (#4030)
* Use the optimal allocation function for opportunistic allocation.

Allocation functions set the `lastAllocation` state also.
This might have been causing an e2e failure with v1 client on migration.

* annotate args
2025-10-26 00:27:41 +05:30
Raja Subramanian a2ce73e0d0 Do not bind buffer if codec is invalid. (#4028)
Seeing cases of codec with zero clock rate. Do not bind to those.
2025-10-25 14:30:30 +05:30
Raja Subramanian 5042c06cb2 Use rtp converter from protocol/utils/rtputil (#4020)
* Use rtp converter from protocol/utils/rtputil

* lock x/tools as counterfeiter needs it
2025-10-22 15:15:46 +05:30
Raja Subramanian 5a426d15e1 Use rtp converter from protocol/utils (#4019) 2025-10-22 14:09:33 +05:30
Alexey Sokolov c039769607 Issue #1 only: Fix spatial layer initialization in Forwarder (#4003)
When SetMaxSpatialLayer() is called with target/current layers in
InvalidLayerSpatial state, opportunistically initialize the target
layer to avoid dropped packets during async stream allocator
initialization.

Guards:
- Only sets target if not congestion-throttled (isDeficientLocked)
- Does not set current layer (deferred to keyframe-based forwarder start)
- Logs at Debug level to avoid log noise

This prevents undefined layer state during manual subscription
with immediate quality upgrades (WithAutoSubscribe(false) +
SetVideoQuality(HIGH)).
2025-10-21 12:54:05 +05:30
Raja Subramanian 2afbf0e8ca Some golang modernisation bits. (#4016)
Mainly doing this to check CI static check failures.
2025-10-21 12:53:18 +05:30
Raja Subramanian dd62eb0072 Resort to full search for requested quality is not available. (#4000)
When doing code changes for dynamic rid, inadventently relied on
ordering of quality in track info layers to pick the highest layer if
the requested quality is higher than available qualities.
@cnderrauber addressed it in
https://github.com/livekit/livekit/pull/3998. Just adding some more
robustness behind that by doing a full search when requested quality is
not available.

Tested using JS SDK demo app and picking different qualities from
subscriber side with adaptive streaming turned off.
2025-10-14 10:05:33 +05:30
Raja Subramanian f6ca82d177 Revert to using silence packets for audio dummy start. (#3999)
Effectively reverts https://github.com/livekit/livekit/pull/3984.
Using padding only packets for audio dummy start introduces dependencies
on other services and is not a necessary change. Would have been good to
use padding only for audio also from t=0. We can re-visit this for
better compatbility down the line.
2025-10-14 10:05:16 +05:30
Raja Subramanian a20bbe34fa Log RPC details. (#3991)
Seeing cases of `ConnectionTimeout` and `ResponseTimeout`.
So, logging destination identity in RPC request and also logging ACK and
response. Will pare back logs/log level of these messages after gettnig
some data.

Also a small change I noticed and had sitting in my local tree to set
the previous RTP marker on a padding packet.
2025-10-09 00:16:56 +05:30
Raja Subramanian 158496bca1 Increment RTP timestamp on padding when using dummy start. (#3989)
* Increment RTP timestamp on padding when using dummy start.

This allows things like egress to have proper sequence to start
the pipeline.

* test
2025-10-07 23:39:51 +05:30
Raja Subramanian 4f6ed65d61 Limit check to red + opus when looking for primary codec match. (#3988)
For codec regression, even if track is encrypted, should be able to fall
back to a backup codec and trigger a regression.
2025-10-07 23:28:26 +05:30
Raja Subramanian bf06596fcb Support Opus mixed with RED when encrypted. (#3986)
Even when encrypted, can set up opus as the second codec to support the
case of RED interspersed with Opus packets when the RED packet is too
big to fit in one packet.

The change here is to not go through all up stream codecs when trying to
find a match in DownTrack.Bind when source is encrypted. When encrypted,
the down track codec should match the primary upstream codec, i. e. the
codec at index 0.
2025-10-07 16:23:28 +05:30
Raja Subramanian 2a6adbe80e Use padding only packets for dummy start of audio. (#3984)
If egress does not need silence packets to start audio, this will
simplify dummy start by using the same mechanism for video and audio.
2025-10-07 10:11:15 +05:30
Raja Subramanian 01337ba730 Do not start forawarding on out-of-order packet. (#3985)
It is posible that a subscriber joins when a publisher has reconnected
and has received a flood of retransmitted packets due to NACKing the
gap caused by the publisher reconnecting. Starting on that spurt means
the subscriber gets a burst of unpaced packets that could lead to issues
with calculating render time (especially obvious in cases like egress).
2025-10-06 13:16:48 +05:30
Raja Subramanian 3bd20ddb28 Revert unintentional change to not handle transport fallback on (#3970)
publisher peer connection.

While cleaning up during single peer connection changes, unintentionally
removed handler.

Also, another small change to log first packet time adjustment after
increment.
2025-09-30 10:24:26 +05:30
Raja Subramanian 735c663adc Update protocol for EventKey helper. (#3963) 2025-09-29 11:42:18 +05:30
Raja Subramanian 0bf7b178eb avoid logging on small values (#3958) 2025-09-28 10:46:41 +05:30
Raja Subramanian 00ff2ab941 Adjust for hold time when fowarding RTCP report. (#3956)
* Adjust for hold time when fowarding RTCP report.

When passing through RTCP sender report, holding it for some time before
sending means the remote receiver could see varying amount of
propagation delay if the remote uses something like local_clock -
ntp_sender_report_time and adapting to it.

Ideally, SFU should just forward RTCP Sender Report, but the current pull model to
group RTCP sender reports makes it a bigger change. So, adjust it by
hold time.

Also add a initial condition for one-way-delay estimator which can init
with a smaller value of latency if the first sample to measure
one-way-delay itself experienced higher delay than the prevailing
conditions.

* variable name

* log as duration
2025-09-26 18:57:21 +05:30
Raja Subramanian bfba6feed4 Adjust stream allocator ping interval based on state. (#3951)
* Adjust stream allocator ping interval based on state.

In steady state, does a 15 second ping.
While deficient, to be able to react to probes faster, it pings at 100ms
interval.

* clean up

* log ops queue not able to wake up
2025-09-24 14:45:57 +05:30
Raja Subramanian 49f9b9c8bd Flush stats when there are no packets. (#3947)
With no packets flowing through, the stat gets stuck.
Flush the pipe if there have been no packets in the report interval.
2025-09-23 16:57:41 +05:30
Raja Subramanian e6a3df1edc ForwarStats.GetStats needs to be public (#3946)
* ForwarStats.GetStats needs to be public

* prevent deadlock
2025-09-23 15:46:12 +05:30
Raja Subramanian 824d116bfe Tweaks tresholds for logging high forwarding latency/jitter. (#3945)
* Tweaks tresholds for logging high forwarding latency/jitter.

Previous attempt showed skewed jitter (i. e. more than 10x latency),
But, no large latency.

So, reducing the latency treshold to declare high latency.
And also keeping track of lowest/highest per reporting window and
logging those along with short term and long term measurements.

NOTE: previously short term and long term were separate calls with locks
acquired. Now, it is all in one lock. So, it does increase the lock
duration a bit, but hopefully not by too much as the welford merge for
short term would go over 20 samples (at 50 ms sampling interval and 1 s
reporting window).

* revert skew factor
2025-09-23 14:46:43 +05:30
Raja Subramanian 408492e030 Log some information around high forwarding latency. (#3944)
* Log some information around high forwarding latency.

Latency is not 0 after switching to microseconds resolution.
But, still seeing high jitter. Logging a bit more to understand under
what conditions it happens.

More notes inline.

* compact
2025-09-23 12:37:09 +05:30
Raja Subramanian 6a41fae548 Use microseconds for forwarding stats. (#3943)
Latency is always 0, but jitter is high.
Not sure how that happens as latency is the welford mean and jitter is
welford standard deviation. Feels like some mis-labeling.

Anyhow, switching to microseconds units to get better resolution.
2025-09-23 02:28:19 +05:30
Raja Subramanian b07e7a3828 Use difference in key frame counter to stop seeder. (#3936)
The key frame seeder could be started multiple times.
Use difference to detect stop condition.
2025-09-19 15:15:26 +05:30
Raja Subramanian 56fb28858a Do DD restart only if DD structure is present. (#3935) 2025-09-19 02:39:08 +05:30
Raja Subramanian 86facce9f4 More debugging of DD jump (#3934) 2025-09-19 01:29:28 +05:30
Raja Subramanian 6058a3f622 Add debugging from DD frame number wrap around. (#3933)
* Add debugging from DD frame number wrap around.

On a DD parser restart, the extended highest sequence number oes not
seem to be updated. Adding some debug to understand it better.

* more logs

* log incoming sequence number and frame number
2025-09-19 00:17:45 +05:30
Raja Subramanian 6489237e33 Simulcast audio fixes (#3925)
* Simulcast audio fixes

* clean up
2025-09-14 09:41:40 +05:30
Raja Subramanian eee2001a31 Set publisher codec preferences after setting remote description (#3913)
* Set publisher codec preferences after setting remote description

Munging SDP prior to setting remote description was becoming problematic
in single peer connection mode. In that mode, it is possible that a
subscribe track m-section is added which sets the fmtp of H.265 to a
value that is different from when that client publishes. That gets
locked in as negotiated codecs when pion processes remote description.
Later when the client publishes H.265, the H.265 does only partial
match. So, if we munge offer and send it to SetRemoteDescription, the
H.265 does only a partial match due to different fmtp line and that gets
put at the end of the list. So, the answer does not enforce the
preferred codec. Changing pion to put partial match up front is more
risky given other projects. So, switch codec preferences to after remote
description is set and directly operate on transceiver which is a better
place to make these changes without munging SDP.

This fixes the case of
- firefox joins first
- Chrome preferring H.265 joining next. This causes a subscribe track
  m-section (for firefox's tracks) to be created first. So, the
  preferred codec munging was not working. Works after this change.

* clean up

* mage generate

* test

* clean up
2025-09-10 18:28:36 +05:30
cnderrauber 76645fad5e Rpcs for ingress proxy WHIP (#3911)
See https://github.com/livekit/protocol/pull/1194
2025-09-09 22:49:42 +08:00
Raja Subramanian 991a4a4f53 Refactor subscribedTrack + mediaTrackSubscriptions. (#3908)
- Move downTrack instantiation to SubscribedTrack as it should own that
  DownTrack. Still more to do here as `DownTrack` is fetched from
  `SubscribedTrack` in a few places and used. Would like to avoid that,
  but doing this initially.
- Use an interface from sfu.Downtrack and replace a bunch of callbacks.
  SubscribedTrack is the implementation for DownTrackListener.
2025-09-08 18:20:19 +05:30
Raja Subramanian 98352fd0f9 Prevent race in determining BWE type. (#3891) 2025-08-30 21:56:11 +05:30
Raja Subramanian f7291fdaa8 Do not send both asb-send-time and twcc. (#3890)
* Do not send both asb-send-time and twcc.

In single peer connection mode, both extensions are set on the media
engine and both would be negotiated. Unfortunately, pion/webrtc does
not yet support RTPSender.SetParameters() which would allow setting
specific header extensions for the sender. So, check for TWCC enabled
and use it. If not, do abs-send-time if that is enabled.

* check BWE type

* comment
2025-08-30 19:22:14 +05:30
cnderrauber 5026de2bea handle frame number wrap back in svc (#3885)
* handle frame number wrap back in svc

* Add Slack Notifier

* check nil dd ext

* log format
2025-08-29 17:11:49 +08:00
Raja Subramanian 998a9f9404 Switch known rids from 012 -> 210, used by OBS. (#3882)
* Switch known rids from 012 -> 210, used by OBS.

* static check
2025-08-28 14:47:57 +05:30
cnderrauber b660c3b582 Extract video size from media stream (#3856)
* Extract video size from media stream

* fix test
2025-08-18 09:06:57 +08:00
Raja Subramanian a370bb2054 Support G.711 A-law and U-law (#3849)
* More codecs

* clean up

* clean up

* add to unprocessed for nil mime type

* enhance tests to check for audio codec preferences also
2025-08-13 14:49:07 +05:30
Raja Subramanian fa5f4ef33c Populate SDP cid in track info when available. (#3845)
* Populate SDP cid in track info when available.

- Adding SDP cid to TrackInfo. Browsers like FF uses a different stream
  id for AddTrack and actual SDP offer. So, have to look up using both
  on server side. To make it easier, store both (only if different) in
  TrackInfo.
- Use a codec in TrackInfo for audio also. There is some discussion
  around doing simulcast codec for audio so that something like PSTN can
  use G.711 without any transcoding. So, just keep it consistent between
  audio and video.
- Populate SDP cid when SDP offer is received. It could populate a
  pending track or an already published track if the new offer is for a
  back up codec where the primary codec is already published.
- Passed around parsed offer to more places to avoid parsing multiple
  times.
- Clean up MediaTrack interface a bit and remove unneeded methods.

* WIP

* WIP

* deps

* stream allocator mime aware

* clean up

* populate SDP cid before munging

* interface methods
2025-08-13 10:53:16 +05:30
Raja Subramanian 1b2289137d Support video layer mode from client and make most of the code mime aware (#3843) 2025-08-09 21:26:11 +05:30