Przeglądaj źródła

fix(SDP): Negotiate only baseline H.264 codecs for p2p.

Chrome on macOS recently started offering encoder for higher level (5.2) but decoder only for level 3.1. See https://issues.chromium.org/issues/324930413
Therefore, filter out all H.264 payload types with main and high profiles. Also, sort all H.264 payload types so that same pt is picked for both H.264 encoder and decoder. Fixes random black tile issues across different browsers when H.264 is the preferred codec for p2p.
release-8443
Jaya Allamsetty 1 rok temu
rodzic
commit
a8f8666be3
2 zmienionych plików z 34 dodań i 15 usunięć
  1. 7
    11
      modules/RTC/TraceablePeerConnection.js
  2. 27
    4
      modules/sdp/SDPUtil.js

+ 7
- 11
modules/RTC/TraceablePeerConnection.js Wyświetl plik

1385
 
1385
 
1386
         for (const codec of currentCodecs) {
1386
         for (const codec of currentCodecs) {
1387
             if (this.isP2P) {
1387
             if (this.isP2P) {
1388
-                // Strip the high profile H264 codecs on mobile clients as they deliver better quality at the expense
1389
-                // of higher load.
1390
-                if (codec === CodecMimeType.H264 && browser.isMobileDevice()) {
1391
-                    SDPUtil.stripCodec(mLine, codec, true /* high profile */);
1392
-                }
1393
-
1394
-                // There are multiple VP9 payload types generated by the browser, more payload types are added if the
1395
-                // endpoint doesn't have a local video source. Therefore, strip all the high profile codec variants for
1396
-                // VP9 so that only one payload type for VP9 is negotiated between the peers.
1397
-                if (codec === CodecMimeType.VP9) {
1388
+                // 1. Strip the high profile H264 codecs on all clients. macOS started offering encoder for H.264 level
1389
+                //     5.2 but a decoder only for level 3.1. Therfore, strip all main and high level codecs for H.264.
1390
+                // 2. There are multiple VP9 payload types generated by the browser, more payload types are added if the
1391
+                //     endpoint doesn't have a local video source. Therefore, strip all the high profile codec variants
1392
+                //     for VP9 so that only one payload type for VP9 is negotiated between the peers.
1393
+                if (codec === CodecMimeType.H264 || codec === CodecMimeType.VP9) {
1398
                     SDPUtil.stripCodec(mLine, codec, true /* high profile */);
1394
                     SDPUtil.stripCodec(mLine, codec, true /* high profile */);
1399
                 }
1395
                 }
1400
 
1396
 
1407
 
1403
 
1408
         // Reorder the codecs based on the preferred settings.
1404
         // Reorder the codecs based on the preferred settings.
1409
         for (const codec of this.codecSettings.codecList.slice().reverse()) {
1405
         for (const codec of this.codecSettings.codecList.slice().reverse()) {
1410
-            SDPUtil.preferCodec(mLine, codec);
1406
+            SDPUtil.preferCodec(mLine, codec, this.isP2P);
1411
         }
1407
         }
1412
     }
1408
     }
1413
 
1409
 

+ 27
- 4
modules/sdp/SDPUtil.js Wyświetl plik

617
      * Sets the given codecName as the preferred codec by moving it to the beginning
617
      * Sets the given codecName as the preferred codec by moving it to the beginning
618
      * of the payload types list (modifies the given mline in place). All instances
618
      * of the payload types list (modifies the given mline in place). All instances
619
      * of the codec are moved up.
619
      * of the codec are moved up.
620
-     * @param {object} mLine the mline object from an sdp as parsed by transform.parse
621
-     * @param {string} codecName the name of the preferred codec
620
+     * @param {object} mLine the mline object from an sdp as parsed by transform.parse.
621
+     * @param {string} codecName the name of the preferred codec.
622
+     * @param {boolean} sortPayloadTypes whether the payloadtypes need to be sorted for a given codec.
622
      */
623
      */
623
-    preferCodec(mline, codecName) {
624
+    preferCodec(mline, codecName, sortPayloadTypes = false) {
624
         if (!mline || !codecName) {
625
         if (!mline || !codecName) {
625
             return;
626
             return;
626
         }
627
         }
630
             .map(rtp => rtp.payload);
631
             .map(rtp => rtp.payload);
631
 
632
 
632
         if (matchingPayloadTypes) {
633
         if (matchingPayloadTypes) {
634
+            if (sortPayloadTypes && codecName === CodecMimeType.H264) {
635
+                // Move all the H.264 codecs with packetization-mode=0 to top of the list.
636
+                const payloadsWithMode0 = matchingPayloadTypes.filter(payload => {
637
+                    const fmtp = mline.fmtp.find(item => item.payload === payload);
638
+
639
+                    if (fmtp) {
640
+                        return fmtp.config.includes('packetization-mode=0');
641
+                    }
642
+
643
+                    return false;
644
+                });
645
+
646
+                for (const pt of payloadsWithMode0.reverse()) {
647
+                    const idx = matchingPayloadTypes.findIndex(payloadType => payloadType === pt);
648
+
649
+                    if (idx >= 0) {
650
+                        matchingPayloadTypes.splice(idx, 1);
651
+                        matchingPayloadTypes.unshift(pt);
652
+                    }
653
+                }
654
+            }
655
+
633
             // Call toString() on payloads to get around an issue within SDPTransform that sets
656
             // Call toString() on payloads to get around an issue within SDPTransform that sets
634
             // payloads as a number, instead of a string, when there is only one payload.
657
             // payloads as a number, instead of a string, when there is only one payload.
635
             const payloadTypes
658
             const payloadTypes
686
                     if (codec) {
709
                     if (codec) {
687
                         return codec.toLowerCase() === CodecMimeType.VP9
710
                         return codec.toLowerCase() === CodecMimeType.VP9
688
                             ? !item.config.includes('profile-id=0')
711
                             ? !item.config.includes('profile-id=0')
689
-                            : item.config.includes('profile-level-id=64');
712
+                            : !item.config.includes('profile-level-id=42');
690
                     }
713
                     }
691
 
714
 
692
                     return false;
715
                     return false;

Ładowanie…
Anuluj
Zapisz