Commit Graph

1308 Commits

Author SHA1 Message Date
Raja Subramanian
c2335968de Prevent evaluation over small wkndow. (#1516)
With push model (i. e. connection quality evaluation triggered
by reception of RTCP receiver report), it is possible that a report
is received quickly after a track is started (especially with video).
Those should not trigger a quality evaluation.

Set `lastStatsAt` in `Start` routine and ensure that start has been
called and enough time has passed since last stats time to avoid
small windows.
2023-03-14 16:27:39 +05:30
Raja Subramanian
e0495f6cab Do not calculate distance if max layers are not valid (#1515) 2023-03-14 15:19:50 +05:30
Raja Subramanian
75eb0e01ec Missed return after adding layer transition for screen share (#1514) 2023-03-14 15:06:59 +05:30
Raja Subramanian
fd27a70fe2 stream allocator <-> down track misc changes/clean up (#1512) 2023-03-13 07:45:59 +05:30
David Zhao
5ff72a99b9 Report publish & subscribe RTPStats as Telemetry events (#1506) 2023-03-10 10:28:54 -08:00
Raja Subramanian
e7e8bbe72c Use an interface instead of a lot of callbacks. (#1510) 2023-03-10 23:22:22 +05:30
Raja Subramanian
c70aa616a9 Expected vs actual Layer based connection quality. (#1509)
* Expected vs actual Layer based connection quality.

With VBR streams (like screen share), bit rate is not a good indicator
of whether desired layer (spatial/temporal) is achieved due to high
variance.

Using expected vs actual layer (i. e. distance to desired) can capture
any short fall and include it in quality scoring.

This PR uses distance to desired, i. e. how many steps it would take to
go from actual spatial/temporal -> desired spatial/temporal and that
distance is propotionally used (currently it is just linear) to decrease
score.

* wire up layer transitions for screen share tracks
2023-03-10 13:08:36 +05:30
Raja Subramanian
e893d30fd0 Use EWMA (Exponentially Weighted Moving Average) for score updates. (#1507)
* Use EWMA (Exponentially Weighted Moving Average) for score updates.

Makes code simpler, but makes it harder to test as the inflection points
are not exact.

Score falls a bit slower to be conservative on dropping quality too
quickly. Still fall factor is higher (i. e. newer scores get more
weight) than rise factor (i. e. newer scores get lower weight).
Slower rise factor to introduce hysteresis on things climibing back too
quickly.

In the extreme case, asympttotic conditions could cause unexpected
results. For example, having 4% loss of video continously will never
drop quality to `POOR`. It will get close to 60, but it will always
stay above 60 forever and hence quality will never drop to POOR.
Maybe, need some sort of variable thresholding to deal with that. But,
that is an extreme case and may not happen in real life.

* remove unused stuff
2023-03-09 13:52:01 +05:30
Raja Subramanian
14b0b48b15 Push/pull for connection stats/quality scoring. (#1505)
* Push/pull for connection stats/quality scoring.

Was not happy with pure pull method missing a window because
of RTCP RR timing is slightly off for audio and using a much
larger window of data in the next update.

That also resulted in RTP stats getting some bits of code.
As that is per-packet processing, was not a good idea.

Switching to push-pull method.
For up track, it is pull, i. e. connection stats worker will pull stats.

For down track, there is a new notification about receiver report
reception. Using this to check for time to run stats. And adding a bit
of tolerance for processing window (currently set so that as long as it
is > 95% of usual processing interval). This allows two things
- for video, RTCP RR are more frequent, but we will still not process
  till enough time has passed
- for audio, RTCP RR could be once in 5 seconds or so. Can process when
  it is available rather than miss a window and use a much larger window
  later.

* uber atomic
2023-03-09 11:51:20 +05:30
Paul Wells
54bf7e0dac allow configuring signal message buffer size (#1504)
* allow configuring signal message buffer size

* update psrpc
2023-03-08 17:34:14 -08:00
Paul Wells
2c93d55e5c add stream retry middleware for signalling (#1503) 2023-03-08 00:51:19 -08:00
imcdd
1f4fd6aafe 1. Fix wrong atomic pkg from go1.19 std sync/atomic to go.uber.org/atomic (#1479)
2. Fix CI buildtest config '>=1.18' to '1.18',ensure compatibility with go1.18
2023-03-07 23:27:26 -08:00
cnderrauber
11ae7fdbb6 Don't switch candidate if signal closed when pc failed (#1498)
* Don't switch candidate if signal closed when pc failed

* change comment

* test case
2023-03-08 15:16:40 +08:00
lukasIO
958d2f8284 Add topics to data channel messages (#1489)
* Add topics to data channel messages

* update protocol
2023-03-07 10:41:37 +01:00
Raja Subramanian
99601e6d41 Handle the case of no packets in down stream tracks better. (#1500) 2023-03-07 14:32:43 +05:30
cnderrauber
38deab8991 Send room update while client reconnecting (#1499) 2023-03-07 15:59:40 +08:00
Raja Subramanian
d2e7818eca Do not enable bitrate based scoring for screen share. (#1497) 2023-03-07 09:59:10 +05:30
Raja Subramanian
04269c100c Connection quality misc changes (#1496)
* Connectino quality misc changes

1. Call scorer.Update() with nil stat when no data available so that
   scorer can synthesise window with proper window time.
2. Substract out loss in interval to account for packets not sent at
   all.
3. Fix `packetsNotFound` variable in `getIntervalStats`. I remember this
   working at some point. Not sure if I fat fingered in another PR and
   deleted the increment line.
4. Logging a bit more when no packets expected. Those can get noisy
   especially when track is muted. But, seeing some unexplained
   instances of no packets leading to quality drop. So, temporary logging
   to get a bit more information.

* correct spelling

* Limit packet score minimum to 0.0
2023-03-07 09:08:19 +05:30
cnderrauber
48cf30ba23 Send disconnected participant update for reconnecting user (#1495)
* Send disconnected participant update for reconnecting user

* clean code
2023-03-07 09:13:15 +08:00
Raja Subramanian
e2ebb22b3a Do not log TURN errors with prefix "error when handling datagram" (#1494)
These could happen normally in a poor network.
2023-03-06 12:12:42 +05:30
Raja Subramanian
c3b9849328 Return high quality when there are no tracks. (#1493) 2023-03-06 09:08:02 +05:30
Raja Subramanian
15eae2119c prevent data race (#1492) 2023-03-05 17:32:56 +05:30
Raja Subramanian
ea1a467191 Bitrate based quality tracking for DownTrack (#1491)
* Make connection quality not too optimistic.

With score normalization, the quality indicator showed good
under conditions which should have normally showed some badness.

So, a few things in this PR
- Do not normalize scores
- Pick the weakest link as the representative score (moving away from
  averaging)
- For down track direction, when reporting delta stats, take the number
  of packets sent actually. If there are holes in the feed (upstream
  packet loss), down tracks should not be penalised for that loss.

State of things in connection quality feature
- Audio uses rtcscore-go (with a change to accommodate RED codec). This
  follows the E-model.
- Camera uses rtcscore-go. No change here. NOTE: THe rtscore here is
  purely based on bits per pixel per frame (bpf). This has the following
  existing issues (no change, these were already there)
  o Does not take packet loss, jitter, rtt into account
  o Expected frame rate is not available. So, measured frame rate is
    used as expected frame rate also. If expected frame rate were available,
    the score could be reduced for lower frame rates.
- Screen share tracks: No change. This uses the very old simple loss
  based thresholding for scoring. As the bit rate varies a lot based on
  content and rtcscore video algorithm used for camera relies on
  bits per pixel per frame, this could produce a very low value
  (large width/height encoded in a small number of bits because of static content)
  and hence a low score. So, the old loss based thresholding is used.

* clean up

* update rtcscore pointer

* fix tests

* log lines reformat

* WIP commit

* WIP commit

* update mute of receiver

* WIP commit

* WIP commit

* start adding tests

* take min score if quality matches

* start adding bytes based scoring

* clean up

* more clean up

* Use Fuse

* log quality drop

* Periodically report bitrate to down track.

For connection quality based on bitrate for down tracks,
the measured rate should be used. That is to ensure that
down track quality measurement does not get affected by
publisher side changes negatively (or positively).
Report the optimal bit rate to connection quality scorer
every second so that scorer has a continuously updating
picture of the stream and can compare the actual bit rate
against expected optimal bitrate more reliably.

Doing it at time like allocation, the bitrate may not be
accurate (or may not even be available). So, a periodic update
is necessary.

* add transition at allocation times

* clean up debug log

* - Use number of windows for wait to make things simpler
- track no layer expected case
- always update transition
- always call updateScore
2023-03-05 14:10:19 +05:30
Raja Subramanian
9e327b1f3c Connection quality (#1490)
* Make connection quality not too optimistic.

With score normalization, the quality indicator showed good
under conditions which should have normally showed some badness.

So, a few things in this PR
- Do not normalize scores
- Pick the weakest link as the representative score (moving away from
  averaging)
- For down track direction, when reporting delta stats, take the number
  of packets sent actually. If there are holes in the feed (upstream
  packet loss), down tracks should not be penalised for that loss.

State of things in connection quality feature
- Audio uses rtcscore-go (with a change to accommodate RED codec). This
  follows the E-model.
- Camera uses rtcscore-go. No change here. NOTE: THe rtscore here is
  purely based on bits per pixel per frame (bpf). This has the following
  existing issues (no change, these were already there)
  o Does not take packet loss, jitter, rtt into account
  o Expected frame rate is not available. So, measured frame rate is
    used as expected frame rate also. If expected frame rate were available,
    the score could be reduced for lower frame rates.
- Screen share tracks: No change. This uses the very old simple loss
  based thresholding for scoring. As the bit rate varies a lot based on
  content and rtcscore video algorithm used for camera relies on
  bits per pixel per frame, this could produce a very low value
  (large width/height encoded in a small number of bits because of static content)
  and hence a low score. So, the old loss based thresholding is used.

* clean up

* update rtcscore pointer

* fix tests

* log lines reformat

* WIP commit

* WIP commit

* update mute of receiver

* WIP commit

* WIP commit

* start adding tests

* take min score if quality matches

* start adding bytes based scoring

* clean up

* more clean up

* Use Fuse

* log quality drop

* clean up debug log

* - Use number of windows for wait to make things simpler
- track no layer expected case
- always update transition
- always call updateScore
2023-03-05 12:55:04 +05:30
Paul Wells
e22de045ba add signal psrpc service (#1485)
* add signal psrpc service

* update protocol dep

* refactor for cloud

* update psrpc

* pr feedback
2023-03-03 15:49:46 -08:00
Raja Subramanian
e48c818532 Resync on pub muted for audio to avoid jump in sequence numbers on (#1487)
unmute.
2023-03-03 12:18:25 +05:30
cnderrauber
4277699600 Add option to enable skip tcp ice if tcp rtt is high (#1484)
* Add option to switch tcp ice only if tcp works well

* solve comment

* rename and remove config change
2023-03-01 16:45:39 +08:00
Raja Subramanian
a35eecd03d Fix a case of changing video quality not succeeding. (#1483)
In the following order, got the wrong layer
- Max layer is 0, max published is 0, request layer is 0
- Current locks to 0.
- Max changes to 1. Nothing changes as 1 is not published yet.
- Max published changes to 1.
- As curernt layer is valid, available and locked to request layer, it
  was kept. But, it should have checked if the request layer changed
  and updated accordingly.
2023-03-01 11:12:54 +05:30
Raja Subramanian
ab098d951e Prevent PLI layer lock getting stuck. (#1481)
In the following scenario, PLI layer lock got stuck at the wrong layer
- target is at 2 to allow overshoot
- current gets to 1, but can't get higher because publisher is not
  publishing higher layer
- max layer changed to 0

Because of adjusting for overshoot only when current == target, it never
happened and layer lock PLI kept asking for layer 0. Although, key
frames were received, switch did not happen.

Always check for overshoot adjustment possibility against current layer.
2023-03-01 06:35:41 +05:30
cnderrauber
29fa61068e enable nack if red encoding disabled (#1477) 2023-02-28 12:44:25 +08:00
Raja Subramanian
e423873aa3 Do not include packet in RED if timestamp is too far back. (#1478)
* Do not include packet in RED if timestamp is too far back.

* add test case for large timestmap jump
2023-02-28 10:13:42 +05:30
cnderrauber
c367c36d8f Add config for active red encoding (#1476) 2023-02-28 10:44:47 +08:00
David Zhao
8c43b7b48f Fix unsubscribed speakers stuck as speaking to clients (#1475)
When we unsubscribe from a speaker, SendSpeakerUpdates will drop updates
from that speaker. This has the side effect of dropping the "clearing"
message that we are sending as well.
2023-02-26 23:56:09 -08:00
David Zhao
ade26f7c9e Keep track of pending reconciles to avoid duplicate queueReconcile (#1474) 2023-02-26 23:45:32 -08:00
Raja Subramanian
8e6bcdaffe Change lock scope of access to RTCP sender report data. (#1473)
* Change lock scope of access to RTCP sender report data.

Forwarder calls back to get time stamp offset.
Holding buffer lock is a much bigger scoped lock.

Reduce lock scope and cache latest sender report under its own lock.
And use that cache when calculating time stamp offset.

* move sr cache to stream tracker manager for re-use in relay

* cache before spread
2023-02-27 12:28:25 +05:30
Raja Subramanian
207c97c4b9 Max published layer callback in goroutine (#1472) 2023-02-27 09:20:27 +05:30
Benjamin Pracht
17ae1506f5 Chain twirpLogger and twirpRequestStatusHook properly for the Egress server (#1470) 2023-02-25 15:15:50 -07:00
Raja Subramanian
73399dd565 Encapsulate better. (#1466)
Only `logger` and `trackID` of `trackSubscription` is directly accessed
from outside. They are set at construction time. So, should be fine.
2023-02-24 09:34:03 +05:30
David Zhao
34fcf9e496 Additional case of subscribing to a closed track (#1465)
When the publisher stops publishing, the individual receivers would close
attached DownTracks first before notifying MediaTrackReceiver callbacks.

This means #1454 does not fix the issue entirely since there is still a window
when we can subscribe to a closing track.
2023-02-23 17:07:16 -08:00
David Colburn
3ac2a35c23 check nil video grants (#1463) 2023-02-23 11:30:59 -08:00
cnderrauber
dbb2cdf2b6 switch to tls if tcp ice dose not work well (#1458)
* switch to tls if tcp ice don't work well

* ignore tcp quality too bad
2023-02-23 14:07:50 +08:00
Raja Subramanian
cd0359c898 Reset subscription start timer on permission grant. (#1457)
If not, bind timeout could be reported on permission grant
as it could be using some old timer.
2023-02-23 09:39:33 +05:30
Raja Subramanian
15232560bc Send stream start on initial start (#1456)
A couple of other bits
1. Use request layer for sending PLI on bind and connected.
2. When adjusting for overshoot, do not adjust target unless current is
   at max. If not, it could get stuck in a lower layer in the following
   scenario
      a. Overshoot to layer 2
      b. Max layer is 1, start sending PLI
      c. Get key frame for layer 0, adjust for overshoot as we have
         something at a layer lower than max.
      d. Adjust for overshoot.
      e. Setting target to max means that current and target are equal
         and no further adjustment happens.
2023-02-23 09:35:12 +05:30
Haiyang Wang
15a9ad2b7a fix: unable to notify webhook when egress ending with status EgressStatus_EGRESS_LIMIT_REACHED (#1451) 2023-02-22 12:04:26 -08:00
David Zhao
e855620379 Prevent subscribing to track that's closing (#1454)
Due to the order of events in MediaTrackReceiver and friends, SubscribedTrack
will be closed before the track is removed from RoomTrackManager.

Because of this, when a track is unpublished, it's possible to be subscribed
to the track as it's closing.

By introducing a closing state, we'd prevent accidental subscription to
closing tracks.
2023-02-22 01:14:49 -08:00
cnderrauber
1b3d6fad54 update to utils parallel execute (#1450)
* log change

* remove identity field

* update to protocol parallel execute

* update protocol
2023-02-22 11:09:32 +08:00
Raja Subramanian
6f326be4f7 Do not overshoot when layer is locked. (#1449)
* Do not overshoot when layer is locked.

One more challenging case. When current layer is already locked,
should not set up for overshoot.

* set target to current
2023-02-20 16:41:58 +05:30
Raja Subramanian
d1ce60192c Handle case of layer stop with out bitrate. (#1448)
Missed this in the last commit. Sorry.
The case of
- locking to a layer
- that layer stops
- re-allocation

This should trigger a key frame request to the max available layer.
So, have to set the request layer to max available.
2023-02-20 14:49:32 +05:30
Raja Subramanian
c51d083016 Handle edge case of no published layer (#1446)
* WIP commit

* set max published layer

* split target and request layer
2023-02-20 14:16:46 +05:30
Raja Subramanian
6b55742564 Use available layers in optimal allocation. (#1445)
Addressing edge case where a layer stopped before bitrate could be
measured. Purely bit rate based change deduction missed this as
the before and after did not have bit rates.

Use available layers to look for changes, especially currently
forwarding layer going away.

Also, simplifying bits. Only in the optimal allocation path,
these things are required. When congested, bitrate is always needed.
So, for optimal path, just look at available layer changes and adjust.

Don't need to look for bitrate based layer changes. Clean up that code.
2023-02-19 11:41:40 +05:30