Преглед изворни кода

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 година
родитељ
комит
c9be46e2c3

+ 8
- 0
modules/RTC/MockClasses.js Прегледај датотеку

47
         return Promise.resolve(/* answer */{});
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
      * {@link TraceablePeerConnection.setLocalDescription}.
59
      * {@link TraceablePeerConnection.setLocalDescription}.
52
      *
60
      *

+ 10
- 8
modules/RTC/TPCUtils.js Прегледај датотеку

388
                 const trackIndex = Number(sourceName.split('-')[1].substring(1));
388
                 const trackIndex = Number(sourceName.split('-')[1].substring(1));
389
 
389
 
390
                 if (trackIndex) {
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
     setMediaTransferActive(mediaType, active) {
453
     setMediaTransferActive(mediaType, active) {
451
         const transceivers = this.pc.peerconnection.getTransceivers()
454
         const transceivers = this.pc.peerconnection.getTransceivers()
452
             .filter(t => t.receiver && t.receiver.track && t.receiver.track.kind === mediaType);
455
             .filter(t => t.receiver && t.receiver.track && t.receiver.track.kind === mediaType);
453
-        const localTracks = this.pc.getLocalTracks(mediaType);
454
 
456
 
455
         logger.info(`${this.pc} ${active ? 'Enabling' : 'Suspending'} ${mediaType} media transfer.`);
457
         logger.info(`${this.pc} ${active ? 'Enabling' : 'Suspending'} ${mediaType} media transfer.`);
456
-        transceivers.forEach((transceiver, idx) => {
458
+        transceivers.forEach(transceiver => {
457
             if (active) {
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
                     transceiver.direction = MediaDirection.SENDRECV;
463
                     transceiver.direction = MediaDirection.SENDRECV;
462
                 } else {
464
                 } else {
463
                     transceiver.direction = MediaDirection.RECVONLY;
465
                     transceiver.direction = MediaDirection.RECVONLY;

+ 38
- 3
modules/RTC/TraceablePeerConnection.js Прегледај датотеку

317
      */
317
      */
318
     this._senderMaxHeights = new Map();
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
     // override as desired
327
     // override as desired
321
     this.trace = (what, info) => {
328
     this.trace = (what, info) => {
322
         logger.debug(what, info);
329
         logger.debug(what, info);
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
  * Replaces <tt>oldTrack</tt> with <tt>newTrack</tt> from the peer connection.
2001
  * Replaces <tt>oldTrack</tt> with <tt>newTrack</tt> from the peer connection.
1971
  * Either <tt>oldTrack</tt> or <tt>newTrack</tt> can be null; replacing a valid
2002
  * Either <tt>oldTrack</tt> or <tt>newTrack</tt> can be null; replacing a valid
2011
 
2042
 
2012
         return promise
2043
         return promise
2013
             .then(transceiver => {
2044
             .then(transceiver => {
2045
+                if (oldTrack) {
2046
+                    this.localTracks.delete(oldTrack.rtcId);
2047
+                    this._localTrackTransceiverMids.delete(oldTrack.rtcId);
2048
+                }
2049
+
2014
                 if (newTrack) {
2050
                 if (newTrack) {
2015
                     if (newTrack.isAudioTrack()) {
2051
                     if (newTrack.isAudioTrack()) {
2016
                         this._hasHadAudioTrack = true;
2052
                         this._hasHadAudioTrack = true;
2017
                     } else {
2053
                     } else {
2018
                         this._hasHadVideoTrack = true;
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
                 // Update the local SSRC cache for the case when one track gets replaced with another and no
2060
                 // Update the local SSRC cache for the case when one track gets replaced with another and no
2026
                 // renegotiation is triggered as a result of this.
2061
                 // renegotiation is triggered as a result of this.
2027
                 if (oldTrack && newTrack) {
2062
                 if (oldTrack && newTrack) {

+ 3
- 0
modules/xmpp/JingleSessionPC.js Прегледај датотеку

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

+ 6
- 0
types/auto/modules/RTC/MockClasses.d.ts Прегледај датотеку

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

+ 13
- 0
types/auto/modules/RTC/TraceablePeerConnection.d.ts Прегледај датотеку

267
      * @type {Map<string, number>}
267
      * @type {Map<string, number>}
268
      */
268
      */
269
     _senderMaxHeights: Map<string, number>;
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
     trace: (what: any, info: any) => void;
276
     trace: (what: any, info: any) => void;
271
     onicecandidate: any;
277
     onicecandidate: any;
272
     onTrack: (evt: any) => void;
278
     onTrack: (evt: any) => void;
608
      * was found.
614
      * was found.
609
      */
615
      */
610
     findSenderForTrack(track: any): RTCRtpSender | undefined;
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
      * Replaces <tt>oldTrack</tt> with <tt>newTrack</tt> from the peer connection.
625
      * Replaces <tt>oldTrack</tt> with <tt>newTrack</tt> from the peer connection.
613
      * Either <tt>oldTrack</tt> or <tt>newTrack</tt> can be null; replacing a valid
626
      * Either <tt>oldTrack</tt> or <tt>newTrack</tt> can be null; replacing a valid

Loading…
Откажи
Сачувај