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).
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.
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.
* 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
* 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
* 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
* 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
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.
Due to SDP ordering, Pion did not provide track ID on a receiver.
Pion needs a=msid line to be before a=ssrc line -> need to check if this
is a spec requirement
Because of the above, it had empty id for the receiver in onTrack.
That matched a published track because we do not duplicate SdpCid in
TrackInfo if the SDP cid matches the signal cid. But, the search checks
both and it matched on empty SDP cid.
Do not accept empty ids in searches to prevent this from happening.
* 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
* 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
- 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.