Ver código fonte

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 anos atrás
pai
commit
d744381312

+ 19
- 0
JitsiConference.js Ver arquivo

13
 import * as JitsiTrackErrors from './JitsiTrackErrors';
13
 import * as JitsiTrackErrors from './JitsiTrackErrors';
14
 import * as JitsiTrackEvents from './JitsiTrackEvents';
14
 import * as JitsiTrackEvents from './JitsiTrackEvents';
15
 import authenticateAndUpgradeRole from './authenticateAndUpgradeRole';
15
 import authenticateAndUpgradeRole from './authenticateAndUpgradeRole';
16
+import { CodecSelection } from './modules/RTC/CodecSelection';
16
 import RTC from './modules/RTC/RTC';
17
 import RTC from './modules/RTC/RTC';
17
 import browser from './modules/browser';
18
 import browser from './modules/browser';
18
 import ConnectionQuality from './modules/connectivity/ConnectionQuality';
19
 import ConnectionQuality from './modules/connectivity/ConnectionQuality';
47
     FEATURE_JIGASI,
48
     FEATURE_JIGASI,
48
     JITSI_MEET_MUC_TYPE
49
     JITSI_MEET_MUC_TYPE
49
 } from './modules/xmpp/xmpp';
50
 } from './modules/xmpp/xmpp';
51
+import CodecMimeType from './service/RTC/CodecMimeType';
50
 import * as MediaType from './service/RTC/MediaType';
52
 import * as MediaType from './service/RTC/MediaType';
51
 import VideoType from './service/RTC/VideoType';
53
 import VideoType from './service/RTC/VideoType';
52
 import {
54
 import {
310
 
312
 
311
     const { config } = this.options;
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
     this._statsCurrentId = config.statisticsId ? config.statisticsId : Settings.callStatsUserName;
331
     this._statsCurrentId = config.statisticsId ? config.statisticsId : Settings.callStatsUserName;
314
     this.room = this.xmpp.createRoom(
332
     this.room = this.xmpp.createRoom(
315
         this.options.name, {
333
         this.options.name, {
316
             ...config,
334
             ...config,
335
+            preferredCodec: this.codecSelection.getPreferredCodec(),
317
             statsId: this._statsCurrentId
336
             statsId: this._statsCurrentId
318
         },
337
         },
319
         JitsiConference.resourceCreator
338
         JitsiConference.resourceCreator

+ 190
- 0
modules/RTC/CodecSelection.js Ver arquivo

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 Ver arquivo

287
      */
287
      */
288
     this.senderVideoMaxHeight = null;
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
     // override as desired
290
     // override as desired
331
     this.trace = (what, info) => {
291
     this.trace = (what, info) => {
332
         logger.debug(what, info);
292
         logger.debug(what, info);
1744
     return doesBelong;
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
  * Tells if the given WebRTC <tt>MediaStream</tt> has been added to
1761
  * Tells if the given WebRTC <tt>MediaStream</tt> has been added to
1749
  * the underlying WebRTC PeerConnection.
1762
  * the underlying WebRTC PeerConnection.

+ 38
- 0
modules/xmpp/ChatRoom.js Ver arquivo

166
         // here.
166
         // here.
167
         this.addVideoInfoToPresence(false);
167
         this.addVideoInfoToPresence(false);
168
 
168
 
169
+        // Set the default codec.
170
+        this.addCodecInfoToPresence(this.options.preferredCodec);
171
+
169
         if (options.deploymentInfo && options.deploymentInfo.userRegion) {
172
         if (options.deploymentInfo && options.deploymentInfo.userRegion) {
170
             this.presMap.nodes.push({
173
             this.presMap.nodes.push({
171
                 'tagName': 'region',
174
                 'tagName': 'region',
1556
         this.sendPresence();
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
      * Obtains the info about given media advertised in the MUC presence of
1594
      * Obtains the info about given media advertised in the MUC presence of
1561
      * the participant identified by the given endpoint JID.
1595
      * the participant identified by the given endpoint JID.
1585
             mutedNode = filterNodeFromPresenceJSON(pres, 'audiomuted');
1619
             mutedNode = filterNodeFromPresenceJSON(pres, 'audiomuted');
1586
         } else if (mediaType === MediaType.VIDEO) {
1620
         } else if (mediaType === MediaType.VIDEO) {
1587
             mutedNode = filterNodeFromPresenceJSON(pres, 'videomuted');
1621
             mutedNode = filterNodeFromPresenceJSON(pres, 'videomuted');
1622
+            const codecTypeNode = filterNodeFromPresenceJSON(pres, 'codecType');
1588
             const videoTypeNode = filterNodeFromPresenceJSON(pres, 'videoType');
1623
             const videoTypeNode = filterNodeFromPresenceJSON(pres, 'videoType');
1589
 
1624
 
1590
             if (videoTypeNode.length > 0) {
1625
             if (videoTypeNode.length > 0) {
1591
                 data.videoType = videoTypeNode[0].value;
1626
                 data.videoType = videoTypeNode[0].value;
1592
             }
1627
             }
1628
+            if (codecTypeNode.length > 0) {
1629
+                data.codecType = codecTypeNode[0].value;
1630
+            }
1593
         } else {
1631
         } else {
1594
             logger.error(`Unsupported media type: ${mediaType}`);
1632
             logger.error(`Unsupported media type: ${mediaType}`);
1595
 
1633
 

+ 41
- 27
modules/xmpp/JingleSessionPC.js Ver arquivo

3
 import { getLogger } from 'jitsi-meet-logger';
3
 import { getLogger } from 'jitsi-meet-logger';
4
 import { $iq, Strophe } from 'strophe.js';
4
 import { $iq, Strophe } from 'strophe.js';
5
 
5
 
6
-import CodecMimeType from '../../service/RTC/CodecMimeType';
7
 import RTCEvents from '../../service/RTC/RTCEvents';
6
 import RTCEvents from '../../service/RTC/RTCEvents';
8
 import {
7
 import {
9
     ICE_DURATION,
8
     ICE_DURATION,
56
  * @property {boolean} gatherStats - Described in the config.js[1].
55
  * @property {boolean} gatherStats - Described in the config.js[1].
57
  * @property {object} p2p - Peer to peer related options (FIXME those could be
56
  * @property {object} p2p - Peer to peer related options (FIXME those could be
58
  * fetched from config.p2p on the upper level).
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
  * @property {boolean} preferH264 - Described in the config.js[1].
58
  * @property {boolean} preferH264 - Described in the config.js[1].
62
  * @property {Object} testing - Testing and/or experimental options.
59
  * @property {Object} testing - Testing and/or experimental options.
63
  * @property {boolean} webrtcIceUdpDisable - Described in the config.js[1].
60
  * @property {boolean} webrtcIceUdpDisable - Described in the config.js[1].
333
         pcOptions.videoQuality = options.videoQuality;
330
         pcOptions.videoQuality = options.videoQuality;
334
         pcOptions.forceTurnRelay = options.forceTurnRelay;
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
         if (this.isP2P) {
333
         if (this.isP2P) {
343
             // simulcast needs to be disabled for P2P (121) calls
334
             // simulcast needs to be disabled for P2P (121) calls
344
             pcOptions.disableSimulcast = true;
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
             const abtestSuspendVideo = this._abtestSuspendVideoEnabled(options);
336
             const abtestSuspendVideo = this._abtestSuspendVideoEnabled(options);
359
 
337
 
360
             if (typeof abtestSuspendVideo !== 'undefined') {
338
             if (typeof abtestSuspendVideo !== 'undefined') {
365
             pcOptions.disableSimulcast
343
             pcOptions.disableSimulcast
366
                 = options.disableSimulcast
344
                 = options.disableSimulcast
367
                     || (options.preferH264 && !options.disableH264);
345
                     || (options.preferH264 && !options.disableH264);
368
-            pcOptions.preferH264 = options.preferH264;
369
 
346
 
370
             // disable simulcast for screenshare and set the max bitrate to
347
             // disable simulcast for screenshare and set the max bitrate to
371
             // 500Kbps if the testing flag is present in config.js.
348
             // 500Kbps if the testing flag is present in config.js.
902
         }
879
         }
903
     }
880
     }
904
 
881
 
882
+    /**
883
+     *
884
+     */
885
+    getConfiguredVideoCodec() {
886
+        return this.peerconnection.getConfiguredVideoCodec();
887
+    }
888
+
905
     /* eslint-disable max-params */
889
     /* eslint-disable max-params */
906
     /**
890
     /**
907
      * Accepts incoming Jingle 'session-initiate' and should send
891
      * Accepts incoming Jingle 'session-initiate' and should send
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
     /* eslint-enable max-params */
1123
     /* eslint-enable max-params */
1119
 
1124
 
1120
     /**
1125
     /**
1808
             sdp: remoteSdp
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
     /**

Carregando…
Cancelar
Salvar