浏览代码

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.
release-8443
Jaya Allamsetty 2 年前
父节点
当前提交
24c9cc0aac
共有 2 个文件被更改,包括 48 次插入26 次删除
  1. 11
    0
      modules/RTC/TraceablePeerConnection.js
  2. 37
    26
      modules/xmpp/JingleSessionPC.js

+ 11
- 0
modules/RTC/TraceablePeerConnection.js 查看文件

182
     /**
182
     /**
183
      * The set of remote SSRCs seen so far.
183
      * The set of remote SSRCs seen so far.
184
      * Distinguishes new SSRCs from those that have been remapped.
184
      * Distinguishes new SSRCs from those that have been remapped.
185
+     * @type {Set<number>}
185
      */
186
      */
186
     this.remoteSSRCs = new Set();
187
     this.remoteSSRCs = new Set();
187
 
188
 
189
+    /**
190
+     * Mapping of source-names and their associated SSRCs that have been signaled by the JVB.
191
+     * @type {Map<string, number>}
192
+     */
193
+    this.remoteSources = new Map();
194
+
188
     /**
195
     /**
189
      * The local ICE username fragment for this session.
196
      * The local ICE username fragment for this session.
190
      */
197
      */
1185
 
1192
 
1186
     toBeRemoved.dispose();
1193
     toBeRemoved.dispose();
1187
     const participantId = toBeRemoved.getParticipantId();
1194
     const participantId = toBeRemoved.getParticipantId();
1195
+
1196
+    if (!participantId && FeatureFlags.isSsrcRewritingSupported()) {
1197
+        return;
1198
+    }
1188
     const userTracksByMediaType = this.remoteTracks.get(participantId);
1199
     const userTracksByMediaType = this.remoteTracks.get(participantId);
1189
 
1200
 
1190
     if (!userTracksByMediaType) {
1201
     if (!userTracksByMediaType) {

+ 37
- 26
modules/xmpp/JingleSessionPC.js 查看文件

1802
      * @returns {void}
1802
      * @returns {void}
1803
      */
1803
      */
1804
     processSourceMap(message, mediaType) {
1804
     processSourceMap(message, mediaType) {
1805
-        const newSources = [];
1805
+        const newSsrcs = [];
1806
 
1806
 
1807
         for (const src of message.mappedSources) {
1807
         for (const src of message.mappedSources) {
1808
-            if (this.peerconnection.addRemoteSsrc(src.ssrc)) {
1809
-                newSources.push(src);
1810
-            } else {
1811
-                const { owner, source, ssrc, videoType } = src;
1812
-                const track = this.peerconnection.getTrackBySSRC(ssrc);
1808
+            // eslint-disable-next-line prefer-const
1809
+            let { owner, source, ssrc, videoType } = src;
1810
+            const isNewSsrc = this.peerconnection.addRemoteSsrc(ssrc, source);
1811
+            let lookupSsrc = ssrc;
1813
 
1812
 
1814
-                if (track) {
1815
-                    logger.debug(`Existing SSRC ${ssrc}: new owner=${owner}, source-name=${source}`);
1813
+            if (isNewSsrc) {
1814
+                newSsrcs.push(src);
1816
 
1815
 
1817
-                    // Update the SSRC owner.
1818
-                    this._signalingLayer.setSSRCOwner(ssrc, owner);
1816
+                // Check if there is an old mapping for the given source and clear the owner on the associated track.
1817
+                const oldSsrc = this.peerconnection.remoteSources.get(source);
1819
 
1818
 
1820
-                    // Update the track with all the relevant info.
1821
-                    track.setSourceName(source);
1822
-                    track.setOwner(owner);
1823
-                    if (mediaType === MediaType.VIDEO) {
1824
-                        const type = videoType === 'CAMERA' ? VideoType.CAMERA : VideoType.DESKTOP;
1819
+                if (oldSsrc) {
1820
+                    lookupSsrc = oldSsrc;
1821
+                    owner = undefined;
1822
+                    source = undefined;
1823
+                }
1824
+            }
1825
+            const track = this.peerconnection.getTrackBySSRC(lookupSsrc);
1825
 
1826
 
1826
-                        track._setVideoType(type);
1827
-                    }
1827
+            if (track) {
1828
+                logger.debug(`Existing SSRC ${ssrc}: new owner=${owner}, source-name=${source}`);
1828
 
1829
 
1829
-                    // Update the muted state on the track since the presence for this track could have been received
1830
-                    // before the updated source map is received on the bridge channel.
1831
-                    const peerMediaInfo = this._signalingLayer.getPeerMediaInfo(owner, mediaType, source);
1830
+                // Update the SSRC owner.
1831
+                this._signalingLayer.setSSRCOwner(ssrc, owner);
1832
 
1832
 
1833
-                    peerMediaInfo && this.peerconnection._sourceMutedChanged(source, peerMediaInfo.muted);
1834
-                } else {
1835
-                    logger.error(`Remote track attached to a remote SSRC=${ssrc} not found`);
1833
+                // Update the track with all the relevant info.
1834
+                track.setSourceName(source);
1835
+                track.setOwner(owner);
1836
+                if (mediaType === MediaType.VIDEO) {
1837
+                    const type = videoType === 'CAMERA' ? VideoType.CAMERA : VideoType.DESKTOP;
1838
+
1839
+                    track._setVideoType(type);
1836
                 }
1840
                 }
1841
+
1842
+                // Update the muted state on the track since the presence for this track could have been received
1843
+                // before the updated source map is received on the bridge channel.
1844
+                const peerMediaInfo = this._signalingLayer.getPeerMediaInfo(owner, mediaType, source);
1845
+
1846
+                peerMediaInfo && this.peerconnection._sourceMutedChanged(source, peerMediaInfo.muted);
1837
             }
1847
             }
1838
         }
1848
         }
1839
 
1849
 
1840
         // Add the new SSRCs to the remote description by generating a source message.
1850
         // Add the new SSRCs to the remote description by generating a source message.
1841
-        if (newSources.length) {
1851
+        if (newSsrcs.length) {
1842
             let node = $build('content', {
1852
             let node = $build('content', {
1843
                 xmlns: 'urn:xmpp:jingle:1',
1853
                 xmlns: 'urn:xmpp:jingle:1',
1844
                 name: mediaType
1854
                 name: mediaType
1847
                 media: mediaType
1857
                 media: mediaType
1848
             });
1858
             });
1849
 
1859
 
1850
-            for (const src of newSources) {
1851
-                const { rtx, ssrc } = src;
1860
+            for (const src of newSsrcs) {
1861
+                const { rtx, ssrc, source } = src;
1852
                 let msid;
1862
                 let msid;
1853
 
1863
 
1854
                 if (mediaType === MediaType.VIDEO) {
1864
                 if (mediaType === MediaType.VIDEO) {
1880
                     msid = `remote-audio-${idx} remote-audio-${idx}`;
1890
                     msid = `remote-audio-${idx} remote-audio-${idx}`;
1881
                 }
1891
                 }
1882
                 _addSourceElement(node, src, ssrc, msid);
1892
                 _addSourceElement(node, src, ssrc, msid);
1893
+                this.peerconnection.remoteSources.set(source, ssrc);
1883
             }
1894
             }
1884
             node = node.up();
1895
             node = node.up();
1885
             this._addOrRemoveRemoteStream(true /* add */, node.node);
1896
             this._addOrRemoveRemoteStream(true /* add */, node.node);

正在加载...
取消
保存