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