Add SVC and Simulcast support for AV1 and VP9. (#2350)
Add SVC and Simulcast support for AV1 and VP9.
The default mode is the full SVC mode for VP9. It works as expected with the current version of JVB.
AV1 in the client is only supported when the bridge negotiates the Dependency Descriptor extension headers which are needed for reading the layer information for AV1 and H.264 video frames.
* feat: Enable H.264 simulcast support.
Multi-encoding simulcast for H.264 is supported now because of the DD header ext support added on the bridge side.
* fix(video-quality): Add default bitrates for all codecs.
Expect the videoQuality settings in the new format, deprecated configs are still supported.
videoQuality: {
AV1: {
maxBitratesVideo: {
low: 100000,
standard: 300000,
high: 1000000,
ssHigh: 1500000
},
useScalabilityModeAPI: {
enabled: true,
useSimulcast: true, //(defaults to SVC),
useKSVC: true //(defaults to L3T3_KEY)
},
},
H264: {
maxBitratesVideo: {
low: 200000,
standard: 500000,
high: 1500000,
ssHigh: 2500000
}
},
VP8: {
maxBitratesVideo: {
low: 200000,
standard: 500000,
high: 1500000,
ssHigh: 2500000
}
},
VP9: {
maxBitratesVideo: {
low: 100000,
standard: 300000,
high: 1200000,
ssHigh: 2500000
},
useScalabilityModeAPI: {
enabled: true,
useSimulcast: true, //(defaults to SVC),
useKSVC: true //(defaults to L3T3_KEY)
},
}
}
* Disable encodings when requested height for screenshare is 0.
* feat: add unit tests for scalability modes.
* ref: Move all encoding configuration calculation to TPCUtils.
* Add more unit tests for VP9 K-SVC mode.
* Make codec name in settings case insensitive.
Also read the deprecated max bitrates correctly, add unit tests to test it.
* ref(TPC): isSimulcastOn -> isSpatialScalabilityOn.
It makes more sense to call it spatial scalability than simulcast now that full SVC support is available.
* fix: Negotiate AV1 DD header exts only for AV1 and H.264.
* fix: Rename setting useL3T3Mode->useKSVC and adjust the defaults.
fix(JingleSession) Use the video type from presence.
Instead of using the videoType from source map signaled by the bridge which can be incorrect if the bridge doesn't receive the presence before it sends out the source map. It uses the default 'camera' as video type if presence is not received from the senders. Possibly fixes a bug where a screenshare source is displayed in the wrong tile after the SSRC is re-mapped.
Additional benefits are:
- ssrc -> source name will be updated on ssrc remap message from
the bridge.
- the map will be correctly cleaned when member leave (this logic was
not working well for _sourceName map)
- Looks cleaner and simpler.
fix(codec-selection) Pick only 1 VP9 codec for p2p negotiation.
More than one VP9 payload type is produced in the offer, more experimental ones if the local endpoint has no local video source. Munge the SDP to remove all codecs besides the one with profile-id=0 so that only one VP9 codec is negotiated with p2p peer.
fix(JingleSession) Modify encoding to stop/start outgoing media on p2p.
This is much faster than changing direction on the transceiver and doesn't need a renegotiation for the suspending/resuming media. Also fixes an issue with audio-only mode in p2p where media doesn't resume when audio-only mode is disabled if it was enabled while the jvb connection was active.
ref(JingleSession) Always call sRD->cA-sLD for renegotiation.
For renegotiations triggered by the application, it is ok to execute sRD->cA-sLD cycle on the p2p initiator instead of executing cO->sLD->sRD cycle. Chrome sometimes creates a third m-line for p2p when createOffer is called which is unexpected and therefore it breaks the client's renegotiation cycle. This has been done in other places already, i.e., when remote sources are signaled, etc. so making it uniform across all renegotiations.
fix(JingleSession): Reject all m-lines associated with sources in source-remove.
Fixes an issue when a screenshare doesn't show up on remote endpoints after one of the endpoints in the call does an ICE RESTART using session-terminate while it has 2 video sources.
* fix(codec-selection) Use a configurable preferred codecs list to select the codecs.
Allow asymmetric codecs to be configured on the endpoints. This means that Firefox and Safari which have bugs with VP9 encode will now encode VP8 but decode VP9 coming in from Chromium endpoints.
* fix(codec-selection) Add unit tests for the codec selection logic.
* feat(codec-selection): Introduce mobileCodecPreferenceOrder setting in config.js.
* fix(codec-selection) Avoid unnecessary renegotiations.
On participant join/leave, check if the new intersection of codecs are already configured to be the top n codecs.
* Address review comments
* fix: Strip the codecs that are not in the codec list from the video m-lines.
Also, ignore remote codecs published in presence for p2p connections.
* fix: Define default codec order for mobile and desktop.
Fix an issue where p2p between mobile and desktop was broken.
* fix: Add default codecs for both p2p and jvb on mobile devices.
Munge the initial offer sent out by RN clients since RN doesn't support RTCRtpTransceiver#setCodecPreferences.
fix(JingleSession) Reconfigure the stream encodings after p2p->jvb switch.
Fixes blurry screenshare in some cases. There is a higher probability of the higher layers getting suspended when all the stream encodings are enabled for low fps SS. Make sure only the highest spatial layer is sent for low fps SS after p2p->jvb switch. Make sure all the stream encodings are enabled for high fps SS after p2p->jvb switch.
fix(JingleSession): Check for source updates after every reneg
Check for source updates and notify the peer of any new sources after every renegotiation cycle. This fixes issues where source changes are not detected if any other task that requires a renegotiation is scheduled between replaceTrack and a negotiationneeded event.
fix(ssrc-rewriting) Update owners when a new SSRC is assigned to existing source.
Fixes a bug where the remote video freezes if the remote user does an ICE restart using session-terminate. In this case, a new SSRC is assigned to the remote source which will have the same source-name.
fix(JingleSession) start modification queue after session is established.
Pull initial offer/answer tasks out of the modification queue and execute them right away. Only track and codec related operations that necessitate a renegotiation cycle need to be pushed to the modification queue. The queue execution is paused until the session is established. This avoids track operations being executed before the session is established. This fixes an issue seen in p2p connections where sources of the initiator are not signaled to the remote since the tracks are added while the initiator is waiting for a session-accept from the peer.
fix(JingleSession) Avoid pushing encodings configuration task to the queue.
When configureSenderVideoEncodings task is pushed to the modification queue, there might not be a setParameters call in progress and this new one will not get chanined to any promise. However, when the task finally is executed, there is a chance for another setParameters method execution to be in progress and can result in setParameters call failing. Also, these extra steps to ensure that the sender encodings are correctly encoded are no longer needed since with multi-stream mode, we do not change the source video type and the previous encodings config will still be valid.
fix(codec-selection) Apply codec preferences to initial offer/answer.
This fixes an issue where p2p clients (with different codec preferences) fail to decode video because the negotiated codecs are removed from the supported codecs list after the media session is established. The codec preferences will be applied when the first offer/answer is created.
fix(TPC) Disable media instead of changing dir for p2p->jvb switch. (#2226)
* fix(TPC) Disable media instead of changing dir for p2p->jvb switch.
Resume or suspend the media on the jvb peerconnection by changing the RTCRtpEncodingParamters.active state instead of changing the direction on the transceiver. This avoids the needs to start a O/A renegotiation cycle for these operations. The media direction will be changed only for p2p lastn=0 case since video needs to be disabled on both the sender and the peer for p2p lastn=0 case.
* Address review comments
* Disable media after adding source while media is suspended on the jvb connection. Default 'active' state for stream encodings after the source is added is 'true'.
* Wait for all the promises to be settled before returning
fix(SignalingLayer) Update SSRC owners on leave. (#2184)
* fix(SignalingLayer) Update SSRC owners on leave.
Update the SSRC owners in the following cases:
1. When a remote endpoint leaves the call.
2. When a source-remove is received.
3. When a source is remapped (with ssrc-rewriting enabled).
Create the remote track even if presence is not yet received. The ssrc owner check prevents the client from creating a dummy track when the call switches over from p2p to jvb when the last remote endpoint leaves the call.
* ref(SignalingLayer) alpha sort methods.
Clean up unused methods, _findEndpointSourceInfoForMediaType is not used anymore.
* squash: Address review comments.
fix(quality-control) Fix receiver constraints for default case.
When the application doesn't set receiver constraints, generate default constraints in the source-name mode.
Cleanup code related to the endpoint based video constraint handling for p2p connection.
fix(p2p) Fix an issue where unmute fails on p2p with channelLastN=0.
Always initiate a sRD->cA->sLD cycle since renegotiation fails in the following scenario.
In a p2p call when channelLastN=0, the direction on the video tranceiver is set to'inactive'.
At this point, if the user unmutes, the track is replaced on the video sender.
If a cO->sLD->sRD is triggered, the browser adds a third m-line which isn't expected and possibly is a bug. All renegotiations fail as a result.
However, the browser does not add a third m-line in the answer it generates and renegotiation succeeds.
1. Checks peer's preferred codec in p2p case. Mobile and web have different preferred codecs.
2. Log an error message when the preferred codec is not offered by JVB.
3. Clean up code related to deprecated config.js settings 'preferH264' and 'disableH264'.
4. Refactor the codec selection logic so that correct codec is picked.
Remove support for legacy endpoint based signaling. (#2147)
* Remove support for legacy endpoint based signaling and make source-name signaling as the only signaling mode. The legacy screensharing mode will no longer be supported. The client will still be able to process remote presence sent in the old format to support interop with very old mobile clients and jigasi that do not support source-name signaling.
* remove code related to presenter mode.
Instead of Jicofo signaling all the remote sources available in the call, the bridge now signals only a limited set of SSRCs and then rewrites the SSRC on the outgoing media streams. The SSRC mapping is done based on the sources requested by the clients through the receiver constraints. This limits the number of m-lines in the remote/local SDPs on the client and therefore results in better performance in large calls.
* Handle source remapping messages from bridge
* Added track_owner_changed events
* don't process an invalid rtx ssrc.
* keep track of remote ssrcs, only renegotiate on new ones.
* Change source name on remote track on ssrc remapping.
* Don't remove tracks on member leave.
* Remove (orphaned) tracks on session terminated.
* Use serial number (per media type) to create msid attribute.
* Update videoType on remapping.
Co-authored-by: James A <jqdrqgnq@users.noreply.github.com>
Fix codec negotiation and other multi-stream issues (#2133)
* fix(codec-selection) Munge all related m-lines for multi-stream.
Munge all the video m-lines to apply the preferred codec settings in multi-stream mode.
* fix(TPC) Cache transceiver mids for all local video tracks.
There will be multiple video tracks in multi-stream, we need to cache the mids for all the the associated transceivers.
* fix(sender-constraints) Do not apply sender constraints if value hasn't changed for a given source.
* fix(TPC) Configure the direction correctly for all m-lines.
Ignore negotiationneeded events for p2p to avoid going into a renegotiation loop.
* squash: Address review comments.
ref(JingleSessionPC): Remove unncessary reneg cycles for p2p.
When an answer is received from the p2p peer, only set remote description instead of calling the full renegotiation cycle. Also, always initiate a sRD->cA->sLD cycle when adding remote sources irrespective of whether the local endpoint is an initiator or responder for the p2p connection. This lets us remove the hacks added for Chromium (unified-plan) bugs related to video not rendering in p2p cases.
ref(RTC) Make the remove and add track method names more generic.
Since Track effects and mute/unmute operations use the same flow, i.e., removing/adding the track from the RTCPeerConnection but not from TPC, make the names of the methods involved more generic.
fix(multi-stream) Set the source name of replaced track before configuring it.
With just source-name enabled, set the source name of the replaced track before configuring the encodings, this fixes an issues where the sender constraints are not applied on the p2p connection because the source name is undefined.
fix(video-quality) Update frame heights in content-modify for p2p. (#1983)
* fix(video-quality) Update frame heights in content-modify for p2p.
When the user changes the preferred video quality settings from the UI, update the frame height values in content-modify for p2p connection when source-name signaling is enabled.
* fix(multi-stream) Send presence for desktop track before signaling when it is the first track to be added to the conference.
Also do not suppress renegotiation for desktop track on p2p since the browser doesn't fire negotiation needed event.
* squash: fix build
* squash: fix linter issues
* squash: add comment.
fix(multi-stream) fix p2p issues with secondary video sources.
* fix(multi-stream) add new m-line when remote adds a second video source in p2p.
A new m-line needs to be added in the remote description when a new secondary video source is signaled by the peer.
* fix(TPC) Suppress lower layers only for screenshare tracks.
With multi-stream support enabled, an extra check for videoType for local track is needed to dtermine if the lower layers need to be suppressed.
* fix(TPC) Mark the direction inactive on inactive media connection.
If a new secondary video source is added on the jvb connection while p2p is active, make sure the direction is set to inactive on the jvb connection, so that no media is being sent out on the jvb connection.
* squash: Address review comments.
fix(multi-stream) Reject m-lines associated with removed sources.
We do not want the client to re-use the inactive transceivers that are associated with m-lines for removed remote tracks. Rejecting a m-line on source-remove clears it from the list of available transceivers.
fix(multi-stream-support) Support muting of desktop track.
* fix(multi-stream-support) Support muting of desktop track.
* fix(multi-stream) Always initiate responder renegotiation even for p2p.
This is needed since the new m-line is always added to the remote description.
* fix(multi-stream) Support multi-stream only on Unfied plan endpoints.
* fix(multi-stream) Advertise source-name signaling to Jicofo when supported.
* fix(JitsiLocalTrack): Remove unnecessary reject.
* fix: add the correct source name attribute for the second video track.
* squash: Address review comments.