瀏覽代碼

fix(codec-selection): Fix codec selection for unified plan browsers.

Make sure the codec order is munged on all the m-lines for unified plan clients. Implement the logic for setting the preferences through RTCRtpTransceiver#setCodecPreferences.
dev1
Jaya Allamsetty 4 年之前
父節點
當前提交
0a13ade32d
No account linked to committer's email address
共有 3 個文件被更改,包括 64 次插入32 次删除
  1. 57
    28
      modules/RTC/TraceablePeerConnection.js
  2. 4
    3
      modules/browser/BrowserCapabilities.js
  3. 3
    1
      modules/xmpp/JingleSessionPC.js

+ 57
- 28
modules/RTC/TraceablePeerConnection.js 查看文件

@@ -1600,34 +1600,42 @@ TraceablePeerConnection.prototype._mungeCodecOrder = function(description) {
1600 1600
     }
1601 1601
 
1602 1602
     const parsedSdp = transform.parse(description.sdp);
1603
-    const mLine = parsedSdp.media.find(m => m.type === this.codecPreference.mediaType);
1604
-
1605
-    if (this.codecPreference.enable) {
1606
-        SDPUtil.preferCodec(mLine, this.codecPreference.mimeType);
1607
-
1608
-        // Strip the high profile H264 codecs on mobile clients for p2p connection.
1609
-        // High profile codecs give better quality at the expense of higher load which
1610
-        // we do not want on mobile clients.
1611
-        // Jicofo offers only the baseline code for the jvb connection.
1612
-        // TODO - add check for mobile browsers once js-utils provides that check.
1613
-        if (this.codecPreference.mimeType === CodecMimeType.H264 && browser.isReactNative() && this.isP2P) {
1614
-            SDPUtil.stripCodec(mLine, this.codecPreference.mimeType, true /* high profile */);
1615
-        }
1616 1603
 
1617
-        // Set the max bitrate here on the SDP so that the configured max. bitrate is effective
1618
-        // as soon as the browser switches to VP9.
1619
-        if (this.codecPreference.mimeType === CodecMimeType.VP9) {
1620
-            const bitrates = Object.values(this.videoBitrates.VP9 || this.videoBitrates);
1621
-
1622
-            // Use only the HD bitrate for now as there is no API available yet for configuring
1623
-            // the bitrates on the individual SVC layers.
1624
-            mLine.bandwidth = [ {
1625
-                type: 'AS',
1626
-                limit: this._isSharingScreen() ? HD_BITRATE : Math.floor(bitrates[2] / 1000)
1627
-            } ];
1604
+    for (const mLine of parsedSdp.media) {
1605
+        if (this.codecPreference.enable && mLine.type === this.codecPreference.mediaType) {
1606
+            SDPUtil.preferCodec(mLine, this.codecPreference.mimeType);
1607
+
1608
+            // Strip the high profile H264 codecs on mobile clients for p2p connection.
1609
+            // High profile codecs give better quality at the expense of higher load which
1610
+            // we do not want on mobile clients.
1611
+            // Jicofo offers only the baseline code for the jvb connection.
1612
+            // TODO - add check for mobile browsers once js-utils provides that check.
1613
+            if (this.codecPreference.mimeType === CodecMimeType.H264 && browser.isReactNative() && this.isP2P) {
1614
+                SDPUtil.stripCodec(mLine, this.codecPreference.mimeType, true /* high profile */);
1615
+            }
1616
+
1617
+            // Set the max bitrate here on the SDP so that the configured max. bitrate is effective
1618
+            // as soon as the browser switches to VP9.
1619
+            if (this.codecPreference.mimeType === CodecMimeType.VP9) {
1620
+                const bitrates = this.videoBitrates.VP9 || this.videoBitrates;
1621
+                const hdBitrate = bitrates.high ? bitrates.high : HD_BITRATE;
1622
+
1623
+                // Use only the HD bitrate for now as there is no API available yet for configuring
1624
+                // the bitrates on the individual SVC layers.
1625
+                mLine.bandwidth = [ {
1626
+                    type: 'AS',
1627
+                    limit: this._isSharingScreen() ? HD_BITRATE : Math.floor(hdBitrate / 1000)
1628
+                } ];
1629
+            } else {
1630
+                // Clear the bandwidth limit in SDP when VP9 is no longer the preferred codec.
1631
+                // This is needed on react native clients as react-native-webrtc returns the
1632
+                // SDP that the application passed instead of returning the SDP off the native side.
1633
+                // This line automatically gets cleared on web on every renegotiation.
1634
+                mLine.bandwidth = undefined;
1635
+            }
1636
+        } else if (mLine.type === this.codecPreference.mediaType) {
1637
+            SDPUtil.stripCodec(mLine, this.codecPreference.mimeType);
1628 1638
         }
1629
-    } else {
1630
-        SDPUtil.stripCodec(mLine, this.codecPreference.mimeType);
1631 1639
     }
1632 1640
 
1633 1641
     return new RTCSessionDescription({
@@ -1862,8 +1870,29 @@ TraceablePeerConnection.prototype.setVideoCodecs = function(preferredCodec = nul
1862 1870
     }
1863 1871
 
1864 1872
     if (browser.supportsCodecPreferences()) {
1865
-        // TODO implement codec preference using RTCRtpTransceiver.setCodecPreferences()
1866
-        // We are using SDP munging for now until all browsers support this.
1873
+        const transceiver = this.peerconnection.getTransceivers()
1874
+            .find(t => t.receiver && t.receiver?.track?.kind === MediaType.VIDEO);
1875
+
1876
+        if (!transceiver) {
1877
+            return;
1878
+        }
1879
+        let capabilities = RTCRtpReceiver.getCapabilities('video').codecs;
1880
+
1881
+        if (enable) {
1882
+            // Move the desired codec (all variations of it as well) to the beginning of the list.
1883
+            /* eslint-disable-next-line arrow-body-style */
1884
+            capabilities.sort(caps => {
1885
+                return caps.mimeType.toLowerCase() === `video/${mimeType}` ? -1 : 1;
1886
+            });
1887
+        } else {
1888
+            capabilities = capabilities.filter(caps => caps.mimeType.toLowerCase() !== `video/${mimeType}`);
1889
+        }
1890
+
1891
+        try {
1892
+            transceiver.setCodecPreferences(capabilities);
1893
+        } catch (err) {
1894
+            logger.warn(`Setting ${mimeType} as ${enable ? 'preferred' : 'disabled'} codec failed`, err);
1895
+        }
1867 1896
     }
1868 1897
 };
1869 1898
 

+ 4
- 3
modules/browser/BrowserCapabilities.js 查看文件

@@ -140,9 +140,10 @@ export default class BrowserCapabilities extends BrowserDetection {
140 140
      */
141 141
     supportsCodecPreferences() {
142 142
         return this.usesUnifiedPlan()
143
-            && typeof window.RTCRtpTransceiver !== 'undefined'
144
-            && Object.keys(window.RTCRtpTransceiver.prototype).indexOf('setCodecPreferences') > -1
145
-            && Object.keys(RTCRtpSender.prototype).indexOf('getCapabilities') > -1
143
+            && Boolean(window.RTCRtpTransceiver
144
+            && window.RTCRtpTransceiver.setCodecPreferences
145
+            && window.RTCRtpReceiver
146
+            && window.RTCRtpReceiver.getCapabilities)
146 147
 
147 148
             // this is not working on Safari because of the following bug
148 149
             // https://bugs.webkit.org/show_bug.cgi?id=215567

+ 3
- 1
modules/xmpp/JingleSessionPC.js 查看文件

@@ -3,6 +3,7 @@
3 3
 import { getLogger } from 'jitsi-meet-logger';
4 4
 import { $iq, Strophe } from 'strophe.js';
5 5
 
6
+import * as MediaType from '../../service/RTC/MediaType';
6 7
 import {
7 8
     ICE_DURATION,
8 9
     ICE_STATE_CHANGED
@@ -341,7 +342,8 @@ export default class JingleSessionPC extends JingleSession {
341 342
             // H264 does not support simulcast, so it needs to be disabled.
342 343
             pcOptions.disableSimulcast
343 344
                 = options.disableSimulcast
344
-                    || (options.preferH264 && !options.disableH264);
345
+                    || (options.preferH264 && !options.disableH264)
346
+                    || (options.videoQuality && options.videoQuality.preferredCodec === MediaType.H264);
345 347
 
346 348
             // disable simulcast for screenshare and set the max bitrate to
347 349
             // 500Kbps if the testing flag is present in config.js.

Loading…
取消
儲存