Commit Graph

78 Commits

Author SHA1 Message Date
David Chen 743d9c8b3a add support for client capabilities (#4461)
* update protocol version

* only check for client capabiltiy to strip packet trailer
2026-04-27 17:58:36 -07:00
Raja Subramanian 6c81f67858 Add subscriber stream start event notification (#4449) 2026-04-14 22:08:31 +05:30
Raja Subramanian 7d06cfca8b Keep subscription synchronous when publisher is expected to resume. (#4424)
Subscription can switch between remote track and local track or
vice-versa. When that happens, closing the subscribed track of one or
the other asynchronously means the re-subscribe could race with
subscribed track closing.

Keeping the case of `isExpectedToResume` sync to prevent the race.

Would be good to support multiple subscribed tracks per subscription.
So, when subscribed track closes, subscription manager can check and
close the correct subscribed track. But, it gets complex to clearly
determine if a subccription is pending or not and other events. So,
keeping it sync.
2026-04-02 19:54:14 +05:30
David Chen a5333a86bb add packet trailer stripping support (#4361)
* bump protocol version to 17 to enable packet trailer stripping functionality
* check subscriber protocol version for trailer stripping
2026-03-23 13:33:42 -07:00
Raja Subramanian b81bac0ec3 Key telemetry stats worker using combination of roomID, participantID (#4323)
Test / test (push) Failing after 17s
Release to Docker / docker (push) Failing after 3m42s
* Key telemetry stats work using combination of roomID, participantID

With forwarded participant, the same participantID can existing in two
rooms.

NOTE: This does not yet allow a participant session to report its
events/track stats into multiple rooms. That would require regitering
multiple listeners (from rooms a participant is forwarded to).

* missed file

* data channel stats

* PR comments + pass in room name so that telemetry events have proper room name also
2026-02-16 13:56:13 +05:30
Anunay Maheshwari 0c33b8c671 chore: move codecs/mime stuff to protocol (#4255) 2026-01-20 20:54:32 +05:30
changgesi d7db7cb389 chore: fix a large number of spelling issues (#4147)
Signed-off-by: changgesi <changgesi@outlook.com>
2025-12-11 09:34:13 +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 c7f625d626 Do not force codec regression between opus and red. (#3980)
The following scenario produced silence audio in egress
1. JS SDK publishing audio/red
2. Egress joins
3. Egress picks the RED primary receiver -> this converts RED to Opus in SFU
4. At the same time, codec regression is triggered back to the publisher. Publisher switches to publishing audio/opus and stops audio/red.
5. But, egress is still attached to audio/red and pulls down only silence.

Fix by checking if the negotiated codec needs publish before sending
subscribed codec udpate.
2025-10-04 00:17:17 +05:30
Raja Subramanian 6489237e33 Simulcast audio fixes (#3925)
* Simulcast audio fixes

* clean up
2025-09-14 09:41:40 +05:30
Raja Subramanian 798fa76110 Support simulcasting of audio (#3920)
* WIP

* WIP

* new files

* clean up

* test

* Deps

* clean up

* clean up

* goimports latest
2025-09-12 10:20:04 +05:30
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 11b240d67d Log track settings more. (#3853) 2025-08-14 20:26:15 +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
Raja Subramanian c69f1aae87 Revert "Temporary change: use pre-defined rids" (#3769)
* Revert "Temporary change: use pre-defined rids (#3767)"

This reverts commit d11da5f5fa.

* clean up

* add test and simplify

* clean up
2025-06-30 07:34:58 +05:30
Raja Subramanian d11da5f5fa Temporary change: use pre-defined rids (#3767)
To address a compatibility issue across relay. Will revert this once the
compatibility is addressed.
2025-06-29 20:00:21 +05:30
Raja Subramanian 670f927ff6 Set and use rid/spatial layer in TrackInfo. (#3724)
* Set and use rid/spatial layer in TrackInfo.

* test
2025-06-12 23:22:11 -07:00
Raja Subramanian 9551c52c85 Try 2 to consolidate mime type (#3407)
* Normalize mime type and add utilities.

An attempt to normalize mime type and avoid string compares remembering
to do case insensitive search.

Not the best solution. Open to ideas. But, define our own mime types
(just in case Pion changes things and Pion also does not have red mime
type defined which should be easy to add though) and tried to use it everywhere.
But, as we get a bunch of callbacks and info from Pion, needed conversion in
more places than I anticipated. And also makes it necessary to carry
that cognitive load of what comes from Pion and needing to process it
properly.

* more locations

* test

* Paul feedback

* MimeType type

* more consolidation

* Remove unused

* test

* test

* mime type as int

* use string method

* Pass error details and timeouts. (#3402)

* go mod tidy (#3408)

* Rename CHANGELOG to CHANGELOG.md (#3391)

Enables markdown features in this otherwise already markdown'ish formatted document

* Update config.go to properly process bool env vars (#3382)

Fixes issue https://github.com/livekit/livekit/issues/3381

* fix(deps): update go deps (#3341)

Generated by renovateBot

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Use a Twirp server hook to send API call details to telemetry. (#3401)

* Use a Twirp server hook to send API call details to telemetry.

* mage generate and clean up

* Add project_id

* deps

* - Redact requests
- Do not store responses
- Extract top level fields room_name, room_id, participant_identity,
  participant_id, track_id as appropriate
- Store status as int

* deps

* Update pkg/sfu/mime/mimetype.go

* Fix prefer codec test

* handle down track mime changes

---------

Co-authored-by: Denys Smirnov <dennwc@pm.me>
Co-authored-by: Philzen <Philzen@users.noreply.github.com>
Co-authored-by: Pablo Fuente Pérez <pablofuenteperez@gmail.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Paul Wells <paulwe@gmail.com>
Co-authored-by: cnderrauber <zengjie9004@gmail.com>
2025-02-10 10:44:15 +05:30
cnderrauber 54f9f7de51 upgrade to pion/webrtc v4 (#3213) 2024-11-28 16:05:38 +08:00
Paul Wells 4deaac2f3f replace proto.Clone calls (#3024)
* replace proto.Clone calls

* deps

* tests
2024-09-18 22:47:33 -07:00
Raja Subramanian ef838e4fa2 Indicate if track is expectd to be resumed in onClose callback. (#2800)
That is the main change. Changed variable name to `isExpectedToResume`
everywhere to be consistent.

Planning to use the callback value in relays to determine if the down
track should be closed or switched to a different up track.
2024-06-17 23:51:00 +05:30
Paul Wells 0f597e7e46 update protocol (#2593)
* update protocol

* cleanup

* deps
2024-03-21 02:48:26 -07:00
Raja Subramanian d20811d1c2 Ignore disabled when adpative stream is enabled. (#2463)
* Ignore `disabled` when adpative stream is enabled.

Due to interplay of adaptive stream/visibility/dynacast, when adaptive
stream is enabled, subscribed track forces visibility and starts
streaming at low quality. This would trigger a render on client and
trigger a visibility update.

So, even if a migration disables a track, upon migration complete and
subscription bind, ignore disable and stream.

* don't hold lock during callback

* don't need to store pubMuted

* don't need to hold settings lock for pub muted
2024-02-08 18:58:48 +05:30
Raja Subramanian f95194c833 Fixes to sync state disabled tracks. (#2459)
* Fixes to sync state disabled tracks.

* test
2024-02-07 13:52:57 +05:30
David Zhao debd75fa15 Integrate logger components (#1933)
* Integrate logger components

Dividing into the following components
* pub - publisher
* pub.sfu
* sub - subscriber
* transport
* transport.pion
* transport.cc
* api
* webhook

* update go modules
2023-08-03 13:31:17 -07:00
Raja Subramanian dbbf2f886f Skip video layer update if sub muted (#1929)
Previous change to check for non-zero width caused test failures
as subscribed track settings can use the quality field and not
necessarily width/height.
2023-08-02 16:33:58 +05:30
Raja Subramanian 0dc92ef273 Remove parked layer feature. (#1927)
* Remove parked layer feature.

Not worth the added complexity.

Several reasons
- Not seeing black frames on pub mute always.
- If they are there, it can consume more than 30kbps if the parked layer
  is high res. That is wasted bandwidth downstream when pub is muted.
- On resume, client some time sends PLI and that triggers a key frame
  request.

But, leaving the separate `PubMuted` flag in forwarder in case we can
use it for better handling.

* need the request spatial
2023-08-02 14:02:29 +05:30
Raja Subramanian 0c34f12fa1 Demote some high frequency logs to Debugw (#1925) 2023-08-02 00:03:38 +05:30
David Zhao 981fb7cac7 Adding license notices (#1913)
* Adding license notices

* remove from config
2023-07-27 16:43:19 -07:00
cnderrauber c1842cb54f Avoid reconnect loop for unsupported downtrack (#1754)
* Avoid reconnect loop for unsupported downtrack

If the client subscribes to a track which codec is unsupported by the
client, sfu will trigger negotiation failed and issue a full reconnect
after received client answer. If the client try to subscribe that track
then it will got full reconnect again. That will cause a infinite
reconnect loop until the client don't subscribe that track. This PR
will unsubscribe the error track for the client and send a
SubscriptionResponse that contain the reason to indicates the track's
codec is not supported to avoid the reconnect loop.
2023-05-31 11:41:22 +08:00
Raja Subramanian ffadb94e3a Simplifying forwarding logic a bit (#1349)
* Notes on wht to do

- Should targetLayers be altered while doing opportunistic locking
- Should targetLayers be altered in any other path than stream allocator path?
- Lock to layer as long as it is <= opportunistic layer
- When not congested, opportunistic can be highest
- When congested, opportunistic could be nil or lowest if paused is not allowed
- When muting, can we hold on to current layers (or keep it as previous) and
  restore on unmute.
- Store current/target in forwarder state and restore on seeding
- Watch for looking for targetLayers, etc. when looking to insert padding
  packets. There may be an assumption about restarting on key frame and hence
  okay to insert padding when target layers are invalid. This may not be true
  any more when doing opportunistic forwarding.
- Can we distinguish between publisher mute or dynacast (i. e. publisher side
  stopping) vs subscriber mute and do something useful? Publisher side mute
  could mean continuity in sequence numbers on a restart (might be able to
  catch it with opportunistic forwarding). But, there is the challenge of
  unmute from publisher via signalling channel vs media. If media is arriving,
  should subscribers do opportunistic forwarding before publisher mute state
  update happens?
- Maybe introduce a mode where forwarding continues to a frame end (of course
  with a time limit just in case the end of frame packet is lost) and then
  insert silence/padding packets?
- Ensure that audio blank frame insertion does not suffer from frame boundary
  issues.

* pub/sub mute separate + more notes on things to check

* WIP commit, more notes

* WIP commit

* WIP commit

* WIP commit

* WIP commit

* WIP commit

* WIP commit

* clean up

* slightly better comments

* Do not stop on unmute

* do not inject blank frames when pub muted

* do not forward on audio publisher mute
2023-02-01 21:57:53 +05:30
David Zhao 5e9221dbd8 Enable video at low res by default when adaptive stream is enabled. (#1341)
When AdaptiveStream is enabled, default the subscriber to LOW quality stream
we would want LOW instead of OFF for a couple of reasons
1. when a subscriber unsubscribes from a track, we would forget their previously defined settings
   depending on client implementation, subscription on/off is kept separately from adaptive stream
   So when there are no changes to desired resolution, but the user re-subscribes, we may leave stream at OFF
2. when interacting with dynacast *and* adaptive stream. If the publisher was not publishing at the
   time of subscription, we might not be able to trigger adaptive stream updates on the client side
   (since there aren't any video frames coming through). this will leave the stream "stuck" on off, without
   a trigger to re-enable it
2023-01-27 20:41:26 -08:00
David Zhao cd6b8b80b9 feat: SubscriptionManager to consolidate subscription handling (#1317)
Added a new manager to handle all subscription needs. Implemented using reconciler pattern. The goals are:

improve subscription resilience by separating desired state and current state
reduce complexity of synchronous processing
better detect failures with the ability to trigger full reconnect
2023-01-24 23:06:16 -08:00
David Zhao 112d6fc18b Reduced log verbosity for pieces that are stable (#1274) 2022-12-29 23:47:36 -08:00
cnderrauber 7a7fc09372 Add fps calculator for VP8 and DependencyDescriptor (#1110)
* Add fps calculator for VP8 and DependencyDescriptor

* clean code

* unit test

* clean code

* solve comment
2022-10-26 09:28:28 +08:00
Raja Subramanian d76f7811e9 An attempt to use consistent layer mapping (#986)
* WIP commit

* Consistent layers.

* slight re-arrangement of code

* log mime

* fix tests

* map -> array
2022-09-07 09:57:31 +05:30
Raja Subramanian fbb1f9fc80 Move subscribe/unsubscribe queue to participant. (#813)
* Move subscribe/unsubscribe queue to participant.

As subscribe/unsubscribe operation can come from both
local media track or remote media track, participant
needs to have it.

* Remove comment

* Stop reneg timer on close

* address comments
2022-07-06 17:27:32 +05:30
Raja Subramanian adf2d191b0 Re-use transceiver (via ReplaceTrack) if a down track is going to be resumed. (#785)
* WIP commit

* Clean up

* spelling mistake

* Run subscribed track onBind in a go routine

* Address comments and more safety net
2022-06-24 15:07:48 +05:30
shishirng cb9f0d37c2 Use rtcscore-go to calculate audio/video score (#689)
* Use rtcscore-go to calculate audio/video score

Signed-off-by: shishir gowda <shishir@livekit.io>

* Get max expected layer and find max actual layer from stream

Signed-off-by: shishir gowda <shishir@livekit.io>

* Cleanup unused methods

Signed-off-by: shishir gowda <shishir@livekit.io>

* Cleanup code - address review comments

Signed-off-by: shishir gowda <shishir@livekit.io>

* get expected layer info instead of just quality

Signed-off-by: shishir gowda <shishir@livekit.io>

* Move SpatialLayerForQuality to utils/helpers

method is required in rtc,sfu and connectionstats pkg
Moved to utils/helpers.go to remove cyclic deps

Signed-off-by: shishir gowda <shishir@livekit.io>

* update tests

Signed-off-by: shishir gowda <shishir@livekit.io>

* Pick stream stats with max layer

Signed-off-by: shishir gowda <shishir@livekit.io>

* Update rtcscore-go pkg to make rtt/jitter optional

when passing 0, rtcscore-go was setting default values

Signed-off-by: shishir gowda <shishir@livekit.io>

* update score to rating

Signed-off-by: shishir gowda <shishir@livekit.io>

* Update rtcscore-go pkg to use simulcast layer info for score

Signed-off-by: shishir gowda <shishir@livekit.io>

* Update score ratings to reflect rtcscore range

Signed-off-by: shishir gowda <shishir@livekit.io>

* update test params for new rtcscore

Signed-off-by: shishir gowda <shishir@livekit.io>

* Delay sending scores to connections only till full data is available

first interval can have partial data leading to lower scores

Signed-off-by: shishir gowda <shishir@livekit.io>

* Check for inf values in quality params

Signed-off-by: shishir gowda <shishir@livekit.io>

* Clean up initial score calculation. Default to 5

Signed-off-by: shishir gowda <shishir@livekit.io>

Co-authored-by: David Zhao <dz@livekit.io>
2022-05-27 14:58:26 -04:00
cnderrauber f958fbcc1c simulcast codecs support (#720)
simulcast codecs support 

Co-authored-by: David Zhao <dz@livekit.io>
2022-05-27 19:55:50 +08:00
Raja Subramanian fe8c355a32 Support participant identity in permissions (#663)
* Support participant identity in permissions

It is harder for clients to update permissions by SID as remote
reconnecting means a new SID for that participant. Using participant
identity is a better option.

For now, participant SID is also supported. Internally, it will
get mapped to identity. Server code uses identity throughout after
doing any necessary conversion from SID -> Identity.

* Address comments
2022-05-02 12:35:20 +05:30
Raja Subramanian cf627d8bbe Send adaptive stream param in join (#626) 2022-04-19 16:45:35 +05:30
Raja Subramanian 75ec31f237 Support starting off with not forwarding video (#623) 2022-04-19 12:37:53 +05:30
David Colburn 0b8a180554 Code inspection (#581)
* Code inspection

* fix [4]int64 conversiong
2022-03-30 13:49:53 -07:00
Raja Subramanian 778d1aa141 utils.AtomicFlag -> atomic.Bool (#466)
* Replacing hand rolled ion-sfu atomic with uber/atomic

* Remove another hand rolled atomic

* utils.AtomicFlag -> atomic.Bool
2022-02-25 12:19:49 +05:30
Raja Subramanian 745939ec24 Smoother dynacast transition (#390) 2022-01-31 07:47:24 +05:30
Raja Subramanian 3bfdb2523e Catch some instances of traversing map outside lock (#388)
* one more place, do not range over map outside lock

* Catch one more location

* Catching a couple of more places
2022-01-29 20:14:36 +05:30
Raja Subramanian 5064f35c29 Refactor media track subscriptions (#314)
* Refactor media track subscriptions

- To enable re-use of common bits
- Add max quality from other nodes

* Lock close handlers slice

* Reverting multiple on close handlers of downtrack, unclear if it is needed yet

* Make Logger a pointer

* audio level in MediaTrack like remote media track

* Cleanup

* Add a no subscribers callback

* Add method to update subscribed quality from another node

* loss proxying from remote node

* Address comments from David

* create subscriber node quality map
2022-01-06 09:02:11 +05:30
boks1971 973420faf5 Revert "Refactor media track subscriptions"
This reverts commit 9ca85454ed.
2022-01-04 16:57:49 +05:30
boks1971 9ca85454ed Refactor media track subscriptions
- To enable re-use of common bits
- Add max quality from other nodes
2022-01-04 16:40:47 +05:30