浏览代码

feat: Add codec selection mechanism.

Determine the preferred codec for a given endpoint based on the config.js settings and the codecs supported by the endpoint.
The preferred codec is published in presence and then used by the other endpoints in the call during join/leave to determine
if the codec needs to be changed on the fly. Different codecs can be configuered for p2p/jvb connections.
The preferredCodec/disabledCodec settings under videoQuality will have precedence over the older settins like preferH264/disableH264.
dev1
Jaya Allamsetty 5 年前
父节点
当前提交
d744381312
共有 5 个文件被更改,包括 341 次插入67 次删除
  1. 19
    0
      JitsiConference.js
  2. 190
    0
      modules/RTC/CodecSelection.js
  3. 53
    40
      modules/RTC/TraceablePeerConnection.js
  4. 38
    0
      modules/xmpp/ChatRoom.js
  5. 41
    27
      modules/xmpp/JingleSessionPC.js

+ 19
- 0
JitsiConference.js 查看文件

@@ -13,6 +13,7 @@ import JitsiTrackError from './JitsiTrackError';
13 13
 import * as JitsiTrackErrors from './JitsiTrackErrors';
14 14
 import * as JitsiTrackEvents from './JitsiTrackEvents';
15 15
 import authenticateAndUpgradeRole from './authenticateAndUpgradeRole';
16
+import { CodecSelection } from './modules/RTC/CodecSelection';
16 17
 import RTC from './modules/RTC/RTC';
17 18
 import browser from './modules/browser';
18 19
 import ConnectionQuality from './modules/connectivity/ConnectionQuality';
@@ -47,6 +48,7 @@ import {
47 48
     FEATURE_JIGASI,
48 49
     JITSI_MEET_MUC_TYPE
49 50
 } from './modules/xmpp/xmpp';
51
+import CodecMimeType from './service/RTC/CodecMimeType';
50 52
 import * as MediaType from './service/RTC/MediaType';
51 53
 import VideoType from './service/RTC/VideoType';
52 54
 import {
@@ -310,10 +312,27 @@ JitsiConference.prototype._init = function(options = {}) {
310 312
 
311 313
     const { config } = this.options;
312 314
 
315
+    // Get the codec preference settings from config.js.
316
+    // 'preferH264' and 'disableH264' settings have been deprecated for a while,
317
+    // 'preferredCodec' and 'disabledCodec' will have precedence over them.
318
+    const codecSettings = {
319
+        disabledCodec: config.videoQuality
320
+            ? config.videoQuality.disabledCodec
321
+            : config.p2p && config.p2p.disableH264 && CodecMimeType.H264,
322
+        enforcePreferredCodec: config.videoQuality && config.videoQuality.enforcePreferredCodec,
323
+        jvbCodec: (config.videoQuality && config.videoQuality.preferredCodec)
324
+            || (config.preferH264 && CodecMimeType.H264),
325
+        p2pCodec: config.p2p
326
+            ? config.p2p.preferredCodec || (config.p2p.preferH264 && CodecMimeType.H264)
327
+            : CodecMimeType.VP8
328
+    };
329
+
330
+    this.codecSelection = new CodecSelection(this, codecSettings);
313 331
     this._statsCurrentId = config.statisticsId ? config.statisticsId : Settings.callStatsUserName;
314 332
     this.room = this.xmpp.createRoom(
315 333
         this.options.name, {
316 334
             ...config,
335
+            preferredCodec: this.codecSelection.getPreferredCodec(),
317 336
             statsId: this._statsCurrentId
318 337
         },
319 338
         JitsiConference.resourceCreator

+ 190
- 0
modules/RTC/CodecSelection.js 查看文件

@@ -0,0 +1,190 @@
1
+
2
+import { getLogger } from 'jitsi-meet-logger';
3
+
4
+import * as JitsiConferenceEvents from '../../JitsiConferenceEvents';
5
+import CodecMimeType from '../../service/RTC/CodecMimeType';
6
+import * as MediaType from '../../service/RTC/MediaType';
7
+import browser from '../browser';
8
+
9
+const logger = getLogger(__filename);
10
+
11
+/**
12
+ * This class handles the codec selection mechanism for the conference based on the config.js settings.
13
+ * The preferred codec is selected based on the settings and the list of codecs supported by the browser.
14
+ * The preferred codec is published in presence which is then used by the other endpoints in the
15
+ * conference to pick a supported codec at join time and when the call transitions between p2p and jvb
16
+ * connections.
17
+ */
18
+export class CodecSelection {
19
+    /**
20
+     * Creates a new instance for a given conference.
21
+     *
22
+     * @param {JitsiConference} conference the conference instance
23
+     * @param {*} options
24
+     * @param {string} options.disabledCodec the codec that needs to be disabled.
25
+     * @param {boolean} options.enforcePreferredCodec whether codec preference has to be
26
+     * enforced even when an endpoints that doesn't support the preferred codec joins the call.
27
+     * Falling back to the standard codec will be skipped when this option is true, endpoints
28
+     * that do not support the preferred codec may not be able to encode/decode video when this happens.
29
+     * @param {string} options.jvbCodec the codec that is preferred on jvb connection.
30
+     * @param {string} options.p2pCodec the codec that is preferred on p2p connection.
31
+     */
32
+    constructor(conference, options) {
33
+        this.conference = conference;
34
+
35
+        // VP8 cannot be disabled and it will be the default codec when no preference is set.
36
+        this.disabledCodec = options.disabledCodec === CodecMimeType.VP8
37
+            ? undefined
38
+            : this._getCodecMimeType(options.disabledCodec);
39
+
40
+        // Check if the codec values passed are valid.
41
+        const jvbCodec = this._getCodecMimeType(options.jvbCodec);
42
+        const p2pCodec = this._getCodecMimeType(options.p2pCodec);
43
+
44
+        this.jvbPreferredCodec = jvbCodec && this._isCodecSupported(jvbCodec) ? jvbCodec : CodecMimeType.VP8;
45
+        this.p2pPreferredCodec = p2pCodec && this._isCodecSupported(p2pCodec) ? p2pCodec : CodecMimeType.VP8;
46
+        this.enforcePreferredCodec = options.enforcePreferredCodec;
47
+
48
+        // Do not prefer VP9 on Firefox because of the following bug.
49
+        // https://bugzilla.mozilla.org/show_bug.cgi?id=1633876
50
+        if (browser.isFirefox() && this.jvbPreferredCodec === CodecMimeType.VP9) {
51
+            this.jvbPreferredCodec = CodecMimeType.VP8;
52
+        }
53
+
54
+        // Keep a list of participants that join the call with a non-preferred codec.
55
+        // The call is upgraded to the preferred codec once that list is empty.
56
+        this.nonPreferredParticipants = [];
57
+
58
+        this.conference.on(
59
+            JitsiConferenceEvents.USER_JOINED,
60
+            this._onParticipantJoined.bind(this));
61
+        this.conference.on(
62
+            JitsiConferenceEvents.USER_LEFT,
63
+            this._onParticipantLeft.bind(this));
64
+        this.conference.on(
65
+            JitsiConferenceEvents._MEDIA_SESSION_STARTED,
66
+            session => this._onMediaSessionStared(session));
67
+    }
68
+
69
+    /**
70
+     * Checks if a given string is a valid video codec mime type.
71
+     *
72
+     * @param {string} codec the codec string that needs to be validated.
73
+     * @returns {CodecMimeType|null} mime type if valid, null otherwise.
74
+     * @private
75
+     */
76
+    _getCodecMimeType(codec) {
77
+        if (typeof codec === 'string') {
78
+            return Object.values(CodecMimeType).find(value => value === codec.toLowerCase());
79
+        }
80
+
81
+        return null;
82
+    }
83
+
84
+    /**
85
+     * Checks if the given codec is supported by the browser.
86
+     *
87
+     * @param {CodecMimeType} preferredCodec codec to be checked.
88
+     * @returns {boolean} true if the given codec is supported, false otherwise.
89
+     * @private
90
+     */
91
+    _isCodecSupported(preferredCodec) {
92
+        // Skip the check on FF and RN because they do not support the getCapabilities API.
93
+        // It is safe to assume both of them support all the codecs supported by Chrome.
94
+        if (browser.isFirefox() || browser.isReactNative()) {
95
+            return true;
96
+        }
97
+
98
+        return window.RTCRtpReceiver
99
+            && window.RTCRtpReceiver.getCapabilities('video').codecs
100
+            .some(codec => codec.mimeType.toLowerCase() === `video/${preferredCodec}`);
101
+    }
102
+
103
+    /**
104
+     * Handles the {@link JitsiConferenceEvents._MEDIA_SESSION_STARTED} event. Codecs need to be
105
+     * configured on the media session that is newly created.
106
+     *
107
+     * @param {JingleSessionPC} mediaSession media session that started.
108
+     * @returns {void}
109
+     * @private
110
+     */
111
+    _onMediaSessionStared(mediaSession) {
112
+        const preferredCodec = mediaSession.isP2P ? this.p2pPreferredCodec : this.jvbPreferredCodec;
113
+        const disabledCodec = this.disabledCodec && this._isCodecSupported(this.disabledCodec)
114
+            ? this.disabledCodec
115
+            : null;
116
+
117
+        mediaSession.setVideoCodecs(preferredCodec, disabledCodec);
118
+    }
119
+
120
+    /**
121
+     * Handles the {@link JitsiConferenceEvents.USER_JOINED} event. When a new user joins the call,
122
+     * the codec types are compared and the codec configued on the peerconnection is updated when
123
+     * needed.
124
+     *
125
+     * @param {string} id endpoint id of the newly joined user.
126
+     * @returns {void}
127
+     * @private
128
+     */
129
+    _onParticipantJoined(id) {
130
+        const session = this.conference.jvbJingleSession;
131
+
132
+        if (session && !this.enforcePreferredCodec) {
133
+            const peerMediaInfo = session.signalingLayer.getPeerMediaInfo(id, MediaType.VIDEO);
134
+
135
+            if (peerMediaInfo) {
136
+                const newCodec = peerMediaInfo.codecType;
137
+                const currentCodec = session.getConfiguredVideoCodec();
138
+
139
+                // Add the participant to the list of participants that
140
+                // don't support the preferred codec.
141
+                if (newCodec !== this.jvbPreferredCodec) {
142
+                    this.nonPreferredParticipants.push(id);
143
+                }
144
+                logger.warn(`Current: ${currentCodec}, new: ${newCodec}`);
145
+                if (newCodec
146
+                    && newCodec !== this.jvbPreferredCodec
147
+                    && newCodec !== currentCodec
148
+                    && this._isCodecSupported(newCodec)) {
149
+                    session.setVideoCodecs(newCodec);
150
+                }
151
+            }
152
+        }
153
+    }
154
+
155
+    /**
156
+     * Handles the {@link JitsiConferenceEvents.USER_LEFT} event. When a user leaves the call,
157
+     * the codec configured on the peerconnection is updated to the preferred codec if all the
158
+     * users that do not support the preferred codec have left the call.
159
+     *
160
+     * @param {string} id endpoint id of the user that has left the call.
161
+     * @returns {void}
162
+     * @private
163
+     */
164
+    _onParticipantLeft(id) {
165
+        const session = this.conference.jvbJingleSession;
166
+
167
+        if (session && !this.enforcePreferredCodec) {
168
+            const index = this.nonPreferredParticipants.findIndex(participantId => participantId === id);
169
+
170
+            if (index > -1) {
171
+                this.nonPreferredParticipants.splice(index, 1);
172
+            }
173
+
174
+            // If all the participants that have joined the conference with a
175
+            // non-preferred codec have left, switch to the preferred codec.
176
+            if (!this.nonPreferredParticipants.length) {
177
+                session.setVideoCodecs(this.jvbPreferredCodec);
178
+            }
179
+        }
180
+    }
181
+
182
+    /**
183
+     * Returns the preferred codec for the conference.
184
+     *
185
+     * @returns {CodecMimeType} preferred codec.
186
+     */
187
+    getPreferredCodec() {
188
+        return this.conference.isP2PActive() ? this.p2pPreferredCodec : this.jvbPreferredCodec;
189
+    }
190
+}

+ 53
- 40
modules/RTC/TraceablePeerConnection.js 查看文件

@@ -287,46 +287,6 @@ export default function TraceablePeerConnection(
287 287
      */
288 288
     this.senderVideoMaxHeight = null;
289 289
 
290
-    // We currently support preferring/disabling video codecs only.
291
-    const getCodecMimeType = codec => {
292
-        if (typeof codec === 'string') {
293
-            return Object.values(CodecMimeType).find(value => value === codec.toLowerCase());
294
-        }
295
-
296
-        return null;
297
-    };
298
-
299
-    // Set the codec preference that will be applied on the SDP based on the config.js settings.
300
-    let preferredCodec = getCodecMimeType(
301
-        this.options.preferredCodec || (this.options.preferH264 && CodecMimeType.H264)
302
-    );
303
-
304
-    // Do not prefer VP9 on Firefox because of the following bug.
305
-    // https://bugzilla.mozilla.org/show_bug.cgi?id=1633876
306
-    if (browser.isFirefox() && preferredCodec === CodecMimeType.VP9) {
307
-        preferredCodec = null;
308
-    }
309
-
310
-    // Determine the codec that needs to be disabled based on config.js settings.
311
-    let disabledCodec = getCodecMimeType(
312
-        this.options.disabledCodec || (this.options.disableH264 && CodecMimeType.H264)
313
-    );
314
-
315
-    // Make sure we don't disable VP8 since it is a mandatory codec.
316
-    if (disabledCodec === CodecMimeType.VP8) {
317
-        logger.warn('Disabling VP8 is not permitted, setting is ignored!');
318
-        disabledCodec = null;
319
-    }
320
-
321
-    if (preferredCodec || disabledCodec) {
322
-        // If both enable and disable are set for the same codec, disable setting will prevail.
323
-        this.codecPreference = {
324
-            enable: disabledCodec === null,
325
-            mediaType: MediaType.VIDEO,
326
-            mimeType: disabledCodec ? disabledCodec : preferredCodec
327
-        };
328
-    }
329
-
330 290
     // override as desired
331 291
     this.trace = (what, info) => {
332 292
         logger.debug(what, info);
@@ -1744,6 +1704,59 @@ TraceablePeerConnection.prototype._assertTrackBelongs = function(
1744 1704
     return doesBelong;
1745 1705
 };
1746 1706
 
1707
+/**
1708
+ * Returns the codec that is configured on the client as the preferred video codec.
1709
+ * This takes into account the current order of codecs in the local description sdp.
1710
+ *
1711
+ * @returns {CodecMimeType} The codec that is set as the preferred codec to receive
1712
+ * video in the local SDP.
1713
+ */
1714
+TraceablePeerConnection.prototype.getConfiguredVideoCodec = function() {
1715
+    const sdp = this.localDescription.sdp;
1716
+    const parsedSdp = transform.parse(sdp);
1717
+    const mLine = parsedSdp.media.find(m => m.type === MediaType.VIDEO);
1718
+    const codec = mLine.rtp[0].codec;
1719
+
1720
+    if (codec) {
1721
+        return Object.values(CodecMimeType).find(value => value === codec.toLowerCase());
1722
+    }
1723
+
1724
+    return CodecMimeType.VP8;
1725
+};
1726
+
1727
+/**
1728
+ * Sets the codec preference on the peerconnection. The codec preference goes into effect when
1729
+ * the next renegotiation happens.
1730
+ *
1731
+ * @param {CodecMimeType} preferredCodec the preferred codec.
1732
+ * @param {CodecMimeType} disabledCodec the codec that needs to be disabled.
1733
+ * @returns {void}
1734
+ */
1735
+TraceablePeerConnection.prototype.setVideoCodecs = function(preferredCodec = null, disabledCodec = null) {
1736
+    // If both enable and disable are set, disable settings will prevail.
1737
+    const enable = disabledCodec === null;
1738
+    const mimeType = disabledCodec ? disabledCodec : preferredCodec;
1739
+
1740
+    if (this.codecPreference && (preferredCodec || disabledCodec)) {
1741
+        this.codecPreference.enable = enable;
1742
+        this.codecPreference.mimeType = mimeType;
1743
+    } else if (preferredCodec || disabledCodec) {
1744
+        this.codecPreference = {
1745
+            enable,
1746
+            mediaType: MediaType.VIDEO,
1747
+            mimeType
1748
+        };
1749
+    } else {
1750
+        logger.warn(`Invalid codec settings: preferred ${preferredCodec}, disabled ${disabledCodec},
1751
+            atleast one value is needed`);
1752
+    }
1753
+
1754
+    if (browser.supportsCodecPreferences()) {
1755
+        // TODO implement codec preference using RTCRtpTransceiver.setCodecPreferences()
1756
+        // We are using SDP munging for now until all browsers support this.
1757
+    }
1758
+};
1759
+
1747 1760
 /**
1748 1761
  * Tells if the given WebRTC <tt>MediaStream</tt> has been added to
1749 1762
  * the underlying WebRTC PeerConnection.

+ 38
- 0
modules/xmpp/ChatRoom.js 查看文件

@@ -166,6 +166,9 @@ export default class ChatRoom extends Listenable {
166 166
         // here.
167 167
         this.addVideoInfoToPresence(false);
168 168
 
169
+        // Set the default codec.
170
+        this.addCodecInfoToPresence(this.options.preferredCodec);
171
+
169 172
         if (options.deploymentInfo && options.deploymentInfo.userRegion) {
170 173
             this.presMap.nodes.push({
171 174
                 'tagName': 'region',
@@ -1556,6 +1559,37 @@ export default class ChatRoom extends Listenable {
1556 1559
         this.sendPresence();
1557 1560
     }
1558 1561
 
1562
+    /**
1563
+     * Add the codec key to the presence map.
1564
+     *
1565
+     * @param {string} codec - the mime type of the codec that needs to be
1566
+     * published via presence to other users in the conference.
1567
+     *
1568
+     * @returns {void}
1569
+     */
1570
+    addCodecInfoToPresence(codec) {
1571
+        this.addToPresence(
1572
+            'codecType',
1573
+            {
1574
+                attributes: { 'xmlns': 'http://jitsi.org/jitmeet/codec' },
1575
+                value: codec.toString()
1576
+            });
1577
+    }
1578
+
1579
+    /**
1580
+     * Adds the codec key to presence map and sends the presence info
1581
+     * to the room.
1582
+     *
1583
+     * @param {string} codec - the mime type of the codec that needs to be
1584
+     * published via presence to other users in the conference.
1585
+     *
1586
+     * @returns {void}
1587
+     */
1588
+    sendCodecInfoPresence(codec) {
1589
+        this.addCodecInfoToPresence(codec);
1590
+        this.sendPresence();
1591
+    }
1592
+
1559 1593
     /**
1560 1594
      * Obtains the info about given media advertised in the MUC presence of
1561 1595
      * the participant identified by the given endpoint JID.
@@ -1585,11 +1619,15 @@ export default class ChatRoom extends Listenable {
1585 1619
             mutedNode = filterNodeFromPresenceJSON(pres, 'audiomuted');
1586 1620
         } else if (mediaType === MediaType.VIDEO) {
1587 1621
             mutedNode = filterNodeFromPresenceJSON(pres, 'videomuted');
1622
+            const codecTypeNode = filterNodeFromPresenceJSON(pres, 'codecType');
1588 1623
             const videoTypeNode = filterNodeFromPresenceJSON(pres, 'videoType');
1589 1624
 
1590 1625
             if (videoTypeNode.length > 0) {
1591 1626
                 data.videoType = videoTypeNode[0].value;
1592 1627
             }
1628
+            if (codecTypeNode.length > 0) {
1629
+                data.codecType = codecTypeNode[0].value;
1630
+            }
1593 1631
         } else {
1594 1632
             logger.error(`Unsupported media type: ${mediaType}`);
1595 1633
 

+ 41
- 27
modules/xmpp/JingleSessionPC.js 查看文件

@@ -3,7 +3,6 @@
3 3
 import { getLogger } from 'jitsi-meet-logger';
4 4
 import { $iq, Strophe } from 'strophe.js';
5 5
 
6
-import CodecMimeType from '../../service/RTC/CodecMimeType';
7 6
 import RTCEvents from '../../service/RTC/RTCEvents';
8 7
 import {
9 8
     ICE_DURATION,
@@ -56,8 +55,6 @@ const DEFAULT_MAX_STATS = 300;
56 55
  * @property {boolean} gatherStats - Described in the config.js[1].
57 56
  * @property {object} p2p - Peer to peer related options (FIXME those could be
58 57
  * fetched from config.p2p on the upper level).
59
- * @property {boolean} p2p.disableH264 - Described in the config.js[1].
60
- * @property {boolean} p2p.preferH264 - Described in the config.js[1].
61 58
  * @property {boolean} preferH264 - Described in the config.js[1].
62 59
  * @property {Object} testing - Testing and/or experimental options.
63 60
  * @property {boolean} webrtcIceUdpDisable - Described in the config.js[1].
@@ -333,28 +330,9 @@ export default class JingleSessionPC extends JingleSession {
333 330
         pcOptions.videoQuality = options.videoQuality;
334 331
         pcOptions.forceTurnRelay = options.forceTurnRelay;
335 332
 
336
-        // codec preference options for jvb connection.
337
-        if (pcOptions.videoQuality) {
338
-            pcOptions.disabledCodec = pcOptions.videoQuality.disabledCodec;
339
-            pcOptions.preferredCodec = pcOptions.videoQuality.preferredCodec;
340
-        }
341
-
342 333
         if (this.isP2P) {
343 334
             // simulcast needs to be disabled for P2P (121) calls
344 335
             pcOptions.disableSimulcast = true;
345
-            pcOptions.disableH264 = options.p2p && options.p2p.disableH264;
346
-            pcOptions.preferH264 = options.p2p && options.p2p.preferH264;
347
-
348
-            // codec preference options for p2p.
349
-            if (options.p2p) {
350
-                // Do not negotiate H246 codec when insertable streams is used because of issues like this -
351
-                // https://bugs.chromium.org/p/webrtc/issues/detail?id=11886
352
-                pcOptions.disabledCodec = options.enableInsertableStreams
353
-                    ? CodecMimeType.H264
354
-                    : options.p2p.disabledCodec;
355
-                pcOptions.preferredCodec = options.p2p.preferredCodec;
356
-            }
357
-
358 336
             const abtestSuspendVideo = this._abtestSuspendVideoEnabled(options);
359 337
 
360 338
             if (typeof abtestSuspendVideo !== 'undefined') {
@@ -365,7 +343,6 @@ export default class JingleSessionPC extends JingleSession {
365 343
             pcOptions.disableSimulcast
366 344
                 = options.disableSimulcast
367 345
                     || (options.preferH264 && !options.disableH264);
368
-            pcOptions.preferH264 = options.preferH264;
369 346
 
370 347
             // disable simulcast for screenshare and set the max bitrate to
371 348
             // 500Kbps if the testing flag is present in config.js.
@@ -902,6 +879,13 @@ export default class JingleSessionPC extends JingleSession {
902 879
         }
903 880
     }
904 881
 
882
+    /**
883
+     *
884
+     */
885
+    getConfiguredVideoCodec() {
886
+        return this.peerconnection.getConfiguredVideoCodec();
887
+    }
888
+
905 889
     /* eslint-disable max-params */
906 890
     /**
907 891
      * Accepts incoming Jingle 'session-initiate' and should send
@@ -1115,6 +1099,27 @@ export default class JingleSessionPC extends JingleSession {
1115 1099
             });
1116 1100
     }
1117 1101
 
1102
+    /**
1103
+     *
1104
+     * @param {*} codec
1105
+     */
1106
+    setVideoCodecs(preferred = null, disabled = null) {
1107
+        const current = this.peerconnection.getConfiguredVideoCodec();
1108
+
1109
+        if (this._assertNotEnded() && preferred !== current) {
1110
+            logger.info(`${this} Switching video codec from ${current} to ${preferred}`);
1111
+            this.peerconnection.setVideoCodecs(preferred, disabled);
1112
+
1113
+            // Initiate a renegotiate for the codec setting to take effect.
1114
+            const workFunction = finishedCallback => {
1115
+                this._renegotiate().then(() => finishedCallback(), error => finishedCallback(error));
1116
+            };
1117
+
1118
+            // Queue and execute
1119
+            this.modificationQueue.push(workFunction);
1120
+        }
1121
+    }
1122
+
1118 1123
     /* eslint-enable max-params */
1119 1124
 
1120 1125
     /**
@@ -1808,11 +1813,20 @@ export default class JingleSessionPC extends JingleSession {
1808 1813
             sdp: remoteSdp
1809 1814
         });
1810 1815
 
1811
-        if (this.isInitiator) {
1812
-            return this._initiatorRenegotiate(remoteDescription);
1813
-        }
1816
+        const promise = this.isInitiator
1817
+            ? this._initiatorRenegotiate(remoteDescription)
1818
+            : this._responderRenegotiate(remoteDescription);
1819
+
1820
+        return promise.then(() => {
1821
+            // Publish the codec info to the other endpoints in the conference if it has changed
1822
+            // as a result of the renegotiation (only on current active session).
1823
+            const codec = this.peerconnection.getConfiguredVideoCodec();
1814 1824
 
1815
-        return this._responderRenegotiate(remoteDescription);
1825
+            if (this.currentCodec !== codec && this._localVideoActive) {
1826
+                this.room.sendCodecInfoPresence(codec);
1827
+                this.currentCodec = codec;
1828
+            }
1829
+        });
1816 1830
     }
1817 1831
 
1818 1832
     /**

正在加载...
取消
保存