Bläddra i källkod

fix(TPC): Switch media direction correctly on all m-lines associated with local tracks during p2p->jvb switch.

Fixes cases where SS stream is not being sent when p2p->jvb switch happens.
dev1
Jaya Allamsetty 2 år sedan
förälder
incheckning
c9be46e2c3

+ 8
- 0
modules/RTC/MockClasses.js Visa fil

@@ -47,6 +47,14 @@ export class MockPeerConnection {
47 47
         return Promise.resolve(/* answer */{});
48 48
     }
49 49
 
50
+    /**
51
+     * {@link TraceablePeerConnection.processLocalSdpForTransceiverInfo}.
52
+     *
53
+     * @returns {void}
54
+     */
55
+    processLocalSdpForTransceiverInfo() {
56
+    }
57
+
50 58
     /**
51 59
      * {@link TraceablePeerConnection.setLocalDescription}.
52 60
      *

+ 10
- 8
modules/RTC/TPCUtils.js Visa fil

@@ -388,9 +388,12 @@ export class TPCUtils {
388 388
                 const trackIndex = Number(sourceName.split('-')[1].substring(1));
389 389
 
390 390
                 if (trackIndex) {
391
-                    transceiver = this.pc.peerconnection.getTransceivers()
392
-                        .filter(t => t.receiver.track.kind === mediaType
393
-                            && t.direction !== MediaDirection.RECVONLY)[trackIndex];
391
+                    transceiver = this.pc.isP2P
392
+                        ? this.pc.peerconnection.getTransceivers()
393
+                            .filter(t => t.receiver.track.kind === mediaType)[trackIndex]
394
+                        : this.pc.peerconnection.getTransceivers()
395
+                            .filter(t => t.receiver.track.kind === mediaType
396
+                                && t.direction !== MediaDirection.RECVONLY)[trackIndex];
394 397
                 }
395 398
             }
396 399
         }
@@ -450,14 +453,13 @@ export class TPCUtils {
450 453
     setMediaTransferActive(mediaType, active) {
451 454
         const transceivers = this.pc.peerconnection.getTransceivers()
452 455
             .filter(t => t.receiver && t.receiver.track && t.receiver.track.kind === mediaType);
453
-        const localTracks = this.pc.getLocalTracks(mediaType);
454 456
 
455 457
         logger.info(`${this.pc} ${active ? 'Enabling' : 'Suspending'} ${mediaType} media transfer.`);
456
-        transceivers.forEach((transceiver, idx) => {
458
+        transceivers.forEach(transceiver => {
457 459
             if (active) {
458
-                // The first transceiver is for the local track and only this one can be set to 'sendrecv'.
459
-                // When multi-stream is enabled, there can be multiple transceivers with outbound streams.
460
-                if (idx < localTracks.length) {
460
+                const localTrackMids = Array.from(this.pc._localTrackTransceiverMids);
461
+
462
+                if (localTrackMids.find(mids => mids[1] === transceiver.mid)) {
461 463
                     transceiver.direction = MediaDirection.SENDRECV;
462 464
                 } else {
463 465
                     transceiver.direction = MediaDirection.RECVONLY;

+ 38
- 3
modules/RTC/TraceablePeerConnection.js Visa fil

@@ -317,6 +317,13 @@ export default function TraceablePeerConnection(
317 317
      */
318 318
     this._senderMaxHeights = new Map();
319 319
 
320
+    /**
321
+     * Holds the RTCRtpTransceiver mids that the local tracks are attached to, mapped per their
322
+     * {@link JitsiLocalTrack.rtcId}.
323
+     * @type {Map<string, string>}
324
+     */
325
+    this._localTrackTransceiverMids = new Map();
326
+
320 327
     // override as desired
321 328
     this.trace = (what, info) => {
322 329
         logger.debug(what, info);
@@ -1966,6 +1973,30 @@ TraceablePeerConnection.prototype.findSenderForTrack = function(track) {
1966 1973
     }
1967 1974
 };
1968 1975
 
1976
+/**
1977
+ * Processes the local description SDP and caches the mids of the mlines associated with the given tracks.
1978
+ *
1979
+ * @param {Array<JitsiLocalTrack>} localTracks - local tracks that are added to the peerconnection.
1980
+ * @returns {void}
1981
+ */
1982
+TraceablePeerConnection.prototype.processLocalSdpForTransceiverInfo = function(localTracks) {
1983
+    const localSdp = this.peerconnection.localDescription?.sdp;
1984
+
1985
+    if (!localSdp) {
1986
+        return;
1987
+    }
1988
+
1989
+    for (const localTrack of localTracks) {
1990
+        const mediaType = localTrack.getType();
1991
+        const parsedSdp = transform.parse(localSdp);
1992
+        const mLine = parsedSdp.media.find(mline => mline.type === mediaType);
1993
+
1994
+        if (!this._localTrackTransceiverMids.has(localTrack.rtcId)) {
1995
+            this._localTrackTransceiverMids.set(localTrack.rtcId, mLine.mid.toString());
1996
+        }
1997
+    }
1998
+};
1999
+
1969 2000
 /**
1970 2001
  * Replaces <tt>oldTrack</tt> with <tt>newTrack</tt> from the peer connection.
1971 2002
  * Either <tt>oldTrack</tt> or <tt>newTrack</tt> can be null; replacing a valid
@@ -2011,17 +2042,21 @@ TraceablePeerConnection.prototype.replaceTrack = function(oldTrack, newTrack) {
2011 2042
 
2012 2043
         return promise
2013 2044
             .then(transceiver => {
2045
+                if (oldTrack) {
2046
+                    this.localTracks.delete(oldTrack.rtcId);
2047
+                    this._localTrackTransceiverMids.delete(oldTrack.rtcId);
2048
+                }
2049
+
2014 2050
                 if (newTrack) {
2015 2051
                     if (newTrack.isAudioTrack()) {
2016 2052
                         this._hasHadAudioTrack = true;
2017 2053
                     } else {
2018 2054
                         this._hasHadVideoTrack = true;
2019 2055
                     }
2056
+                    this._localTrackTransceiverMids.set(newTrack.rtcId, transceiver?.mid?.toString());
2057
+                    this.localTracks.set(newTrack.rtcId, newTrack);
2020 2058
                 }
2021 2059
 
2022
-                oldTrack && this.localTracks.delete(oldTrack.rtcId);
2023
-                newTrack && this.localTracks.set(newTrack.rtcId, newTrack);
2024
-
2025 2060
                 // Update the local SSRC cache for the case when one track gets replaced with another and no
2026 2061
                 // renegotiation is triggered as a result of this.
2027 2062
                 if (oldTrack && newTrack) {

+ 3
- 0
modules/xmpp/JingleSessionPC.js Visa fil

@@ -1044,6 +1044,8 @@ export default class JingleSessionPC extends JingleSession {
1044 1044
                 .then(() => this.peerconnection.createOffer(this.mediaConstraints))
1045 1045
                 .then(offerSdp => this.peerconnection.setLocalDescription(offerSdp))
1046 1046
                 .then(() => {
1047
+                    this.peerconnection.processLocalSdpForTransceiverInfo(localTracks);
1048
+
1047 1049
                     // NOTE that the offer is obtained from the localDescription getter as it needs to go though
1048 1050
                     // the transformation chain.
1049 1051
                     this.sendSessionInitiate(this.peerconnection.localDescription.sdp);
@@ -1188,6 +1190,7 @@ export default class JingleSessionPC extends JingleSession {
1188 1190
             Promise.all(addTracks)
1189 1191
                 .then(() => this._responderRenegotiate(remoteDescription))
1190 1192
                 .then(() => {
1193
+                    this.peerconnection.processLocalSdpForTransceiverInfo(localTracks);
1191 1194
                     if (this.state === JingleSessionState.PENDING) {
1192 1195
                         this.state = JingleSessionState.ACTIVE;
1193 1196
 

+ 6
- 0
types/auto/modules/RTC/MockClasses.d.ts Visa fil

@@ -29,6 +29,12 @@ export class MockPeerConnection {
29 29
      * @returns {Promise<Object>}
30 30
      */
31 31
     createAnswer(): Promise<any>;
32
+    /**
33
+     * {@link TraceablePeerConnection.processLocalSdpForTransceiverInfo}.
34
+     *
35
+     * @returns {void}
36
+     */
37
+    processLocalSdpForTransceiverInfo(): void;
32 38
     /**
33 39
      * {@link TraceablePeerConnection.setLocalDescription}.
34 40
      *

+ 13
- 0
types/auto/modules/RTC/TraceablePeerConnection.d.ts Visa fil

@@ -267,6 +267,12 @@ export default class TraceablePeerConnection {
267 267
      * @type {Map<string, number>}
268 268
      */
269 269
     _senderMaxHeights: Map<string, number>;
270
+    /**
271
+     * Holds the RTCRtpTransceiver mids that the local tracks are attached to, mapped per their
272
+     * {@link JitsiLocalTrack.rtcId}.
273
+     * @type {Map<string, string>}
274
+     */
275
+    _localTrackTransceiverMids: Map<string, string>;
270 276
     trace: (what: any, info: any) => void;
271 277
     onicecandidate: any;
272 278
     onTrack: (evt: any) => void;
@@ -608,6 +614,13 @@ export default class TraceablePeerConnection {
608 614
      * was found.
609 615
      */
610 616
     findSenderForTrack(track: any): RTCRtpSender | undefined;
617
+    /**
618
+     * Processes the local description SDP and caches the mids of the mlines associated with the given tracks.
619
+     *
620
+     * @param {Array<JitsiLocalTrack>} localTracks - local tracks that are added to the peerconnection.
621
+     * @returns {void}
622
+     */
623
+    processLocalSdpForTransceiverInfo(localTracks: Array<any>): void;
611 624
     /**
612 625
      * Replaces <tt>oldTrack</tt> with <tt>newTrack</tt> from the peer connection.
613 626
      * Either <tt>oldTrack</tt> or <tt>newTrack</tt> can be null; replacing a valid

Laddar…
Avbryt
Spara