소스 검색

ref(TPC) Pass the transform object along for SDP munging.

release-8443
Jaya Allamsetty 10 달 전
부모
커밋
07f037e12e
2개의 변경된 파일110개의 추가작업 그리고 123개의 파일을 삭제
  1. 97
    62
      modules/RTC/TPCUtils.js
  2. 13
    61
      modules/RTC/TraceablePeerConnection.js

+ 97
- 62
modules/RTC/TPCUtils.js 파일 보기

@@ -7,6 +7,7 @@ import { MediaDirection } from '../../service/RTC/MediaDirection';
7 7
 import { MediaType } from '../../service/RTC/MediaType';
8 8
 import {
9 9
     SIM_LAYERS,
10
+    SSRC_GROUP_SEMANTICS,
10 11
     STANDARD_CODEC_SETTINGS,
11 12
     VIDEO_QUALITY_LEVELS,
12 13
     VIDEO_QUALITY_SETTINGS
@@ -438,12 +439,11 @@ export class TPCUtils {
438 439
     }
439 440
 
440 441
     /**
441
-     * Ensures that the ssrcs associated with a FID ssrc-group appear in the correct order, i.e.,
442
-     * the primary ssrc first and the secondary rtx ssrc later. This is important for unified
443
-     * plan since we have only one FID group per media description.
444
-     * @param {Object} description the webRTC session description instance for the remote
445
-     * description.
446
-     * @private
442
+     * Ensures that the ssrcs associated with a FID ssrc-group appear in the correct order, i.e., the primary ssrc
443
+     * first and the secondary rtx ssrc later. This is important for unified plan since we have only one FID group per
444
+     * media description.
445
+     * @param {Object} description the webRTC session description instance for the remote description.
446
+     * @returns {Object} the modified webRTC session description instance.
447 447
      */
448 448
     ensureCorrectOrderOfSsrcs(description) {
449 449
         const parsedSdp = transform.parse(description.sdp);
@@ -493,14 +493,15 @@ export class TPCUtils {
493 493
         if (this.pc.usesCodecSelectionAPI() && rtpSender) {
494 494
             const { codecs } = rtpSender.getParameters();
495 495
 
496
-            return codecs[0].mimeType.split('/')[1].toLowerCase();
496
+            if (codecs?.length) {
497
+                return codecs[0].mimeType.split('/')[1].toLowerCase();
498
+            }
497 499
         }
498 500
 
499 501
         const sdp = this.pc.remoteDescription?.sdp;
500
-        const defaultCodec = CodecMimeType.VP8;
501 502
 
502 503
         if (!sdp) {
503
-            return defaultCodec;
504
+            return CodecMimeType.VP8;
504 505
         }
505 506
         const parsedSdp = transform.parse(sdp);
506 507
         const mLine = parsedSdp.media
@@ -512,17 +513,17 @@ export class TPCUtils {
512 513
             return Object.values(CodecMimeType).find(value => value === codec.toLowerCase());
513 514
         }
514 515
 
515
-        return defaultCodec;
516
+        return CodecMimeType.VP8;
516 517
     }
517 518
 
518 519
     /**
519 520
      * Returns the codecs in the current order of preference as configured on the peerconnection.
520 521
      *
521
-     * @param {RTCSessionDescription} - The local description to be used.
522
+     * @param {string} - The local SDP to be used.
522 523
      * @returns {Array}
523 524
      */
524
-    getConfiguredVideoCodecs(description) {
525
-        const currentSdp = description?.sdp ?? this.pc.localDescription?.sdp;
525
+    getConfiguredVideoCodecs(sdp) {
526
+        const currentSdp = sdp ?? this.pc.localDescription?.sdp;
526 527
 
527 528
         if (!currentSdp) {
528 529
             return [];
@@ -574,6 +575,57 @@ export class TPCUtils {
574 575
         } ];
575 576
     }
576 577
 
578
+    /**
579
+     * Injects a 'SIM' ssrc-group line for simulcast into the given session description object to make Jicofo happy.
580
+     * This is needed only for Firefox since it does not generate it when simulcast is enabled.
581
+     *
582
+     * @param desc A session description object (with 'type' and 'sdp' fields)
583
+     * @return A session description object with its sdp field modified to contain an inject ssrc-group for simulcast.
584
+     */
585
+    injectSsrcGroupForUnifiedSimulcast(desc) {
586
+        const sdp = transform.parse(desc.sdp);
587
+        const video = sdp.media.find(mline => mline.type === 'video');
588
+
589
+        // Check if the browser supports RTX, add only the primary ssrcs to the SIM group if that is the case.
590
+        video.ssrcGroups = video.ssrcGroups || [];
591
+        const fidGroups = video.ssrcGroups.filter(group => group.semantics === SSRC_GROUP_SEMANTICS.FID);
592
+
593
+        if (video.simulcast || video.simulcast_03) {
594
+            const ssrcs = [];
595
+
596
+            if (fidGroups && fidGroups.length) {
597
+                fidGroups.forEach(group => {
598
+                    ssrcs.push(group.ssrcs.split(' ')[0]);
599
+                });
600
+            } else {
601
+                video.ssrcs.forEach(ssrc => {
602
+                    if (ssrc.attribute === 'msid') {
603
+                        ssrcs.push(ssrc.id);
604
+                    }
605
+                });
606
+            }
607
+            if (video.ssrcGroups.find(group => group.semantics === SSRC_GROUP_SEMANTICS.SIM)) {
608
+                // Group already exists, no need to do anything
609
+                return desc;
610
+            }
611
+
612
+            // Add a SIM group for every 3 FID groups.
613
+            for (let i = 0; i < ssrcs.length; i += 3) {
614
+                const simSsrcs = ssrcs.slice(i, i + 3);
615
+
616
+                video.ssrcGroups.push({
617
+                    semantics: SSRC_GROUP_SEMANTICS.SIM,
618
+                    ssrcs: simSsrcs.join(' ')
619
+                });
620
+            }
621
+        }
622
+
623
+        return {
624
+            type: desc.type,
625
+            sdp: transform.write(sdp)
626
+        };
627
+    }
628
+
577 629
     /**
578 630
      * Takes in a *unified plan* offer and inserts the appropriate parameters for adding simulcast receive support.
579 631
      * @param {Object} desc - A session description object
@@ -659,26 +711,22 @@ export class TPCUtils {
659 711
     /**
660 712
      * Munges the session description to ensure that the codec order is as per the preferred codec settings.
661 713
      *
662
-     * @param {RTCSessionDescription} description - the local/remote description to be munged.
663
-     * @returns {RTCSessionDescription} - the munged local/remote description.
714
+     * @param {transform.SessionDescription} parsedSdp that needs to be munged
715
+     * @returns {transform.SessionDescription} the munged SDP.
664 716
      */
665
-    mungeCodecOrder(description) {
717
+    mungeCodecOrder(parsedSdp) {
666 718
         const codecSettings = this.pc.codecSettings;
667 719
 
668 720
         if (!codecSettings) {
669
-            return description;
721
+            return parsedSdp;
670 722
         }
671 723
 
724
+        const mungedSdp = parsedSdp;
672 725
         const { isP2P } = this.options;
673
-        const parsedSdp = transform.parse(description.sdp);
674
-        const mLines = parsedSdp.media.filter(m => m.type === codecSettings.mediaType);
675
-
676
-        if (!mLines.length) {
677
-            return description;
678
-        }
726
+        const mLines = mungedSdp.media.filter(m => m.type === codecSettings.mediaType);
679 727
 
680 728
         for (const mLine of mLines) {
681
-            const currentCodecs = this.getConfiguredVideoCodecs(description);
729
+            const currentCodecs = this.getConfiguredVideoCodecs(transform.write(parsedSdp));
682 730
 
683 731
             for (const codec of currentCodecs) {
684 732
                 if (isP2P) {
@@ -707,28 +755,25 @@ export class TPCUtils {
707 755
             }
708 756
         }
709 757
 
710
-        return {
711
-            type: description.type,
712
-            sdp: transform.write(parsedSdp)
713
-        };
758
+        return mungedSdp;
714 759
     }
715 760
 
716 761
     /**
717 762
      * Munges the stereo flag as well as the opusMaxAverageBitrate in the SDP, based on values set through config.js,
718 763
      * if present.
719 764
      *
720
-     * @param {RTCSessionDescription} description that needs to be munged.
721
-     * @returns {RTCSessionDescription} the munged description.
765
+     * @param {transform.SessionDescription} parsedSdp that needs to be munged.
766
+     * @returns {transform.SessionDescription} the munged SDP.
722 767
      */
723
-    mungeOpus(description) {
768
+    mungeOpus(parsedSdp) {
724 769
         const { audioQuality } = this.options;
725 770
 
726 771
         if (!audioQuality?.enableOpusDtx && !audioQuality?.stereo && !audioQuality?.opusMaxAverageBitrate) {
727
-            return description;
772
+            return parsedSdp;
728 773
         }
729 774
 
730
-        const parsedSdp = transform.parse(description.sdp);
731
-        const mLines = parsedSdp.media.filter(m => m.type === MediaType.AUDIO);
775
+        const mungedSdp = parsedSdp;
776
+        const mLines = mungedSdp.media.filter(m => m.type === MediaType.AUDIO);
732 777
 
733 778
         for (const mLine of mLines) {
734 779
             const { payload } = mLine.rtp.find(protocol => protocol.codec === CodecMimeType.OPUS);
@@ -780,30 +825,27 @@ export class TPCUtils {
780 825
             fmtpOpus.config = mungedConfig.trim();
781 826
         }
782 827
 
783
-        return {
784
-            type: description.type,
785
-            sdp: transform.write(parsedSdp)
786
-        };
828
+        return mungedSdp;
787 829
     }
788 830
 
789 831
     /**
790
-     * Munges the session description by setting the max bitrates on the video m-lines when VP9 K-SVC codec is in use.
832
+     * Munges the session SDP by setting the max bitrates on the video m-lines when VP9 K-SVC codec is in use.
791 833
      *
792
-     * @param {RTCSessionDescription} description - The local/remote description that needs to be munged.
834
+     * @param {transform.SessionDescription} parsedSdp that needs to be munged.
793 835
      * @param {boolean} isLocalSdp - Whether the max bitrate (via b=AS line in SDP) is set on local SDP.
794
-     * @returns {RTCSessionDescription} - The munged local/remote description.
836
+     * @returns {transform.SessionDescription} The munged SDP.
795 837
      */
796
-    setMaxBitrates(description, isLocalSdp = false) {
838
+    setMaxBitrates(parsedSdp, isLocalSdp = false) {
797 839
         const pcCodecSettings = this.pc.codecSettings;
798 840
 
799 841
         if (!pcCodecSettings) {
800
-            return description;
842
+            return parsedSdp;
801 843
         }
802
-        const parsedSdp = transform.parse(description.sdp);
803 844
 
804 845
         // Find all the m-lines associated with the local sources.
846
+        const mungedSdp = parsedSdp;
805 847
         const direction = isLocalSdp ? MediaDirection.RECVONLY : MediaDirection.SENDONLY;
806
-        const mLines = parsedSdp.media.filter(m => m.type === MediaType.VIDEO && m.direction !== direction);
848
+        const mLines = mungedSdp.media.filter(m => m.type === MediaType.VIDEO && m.direction !== direction);
807 849
         const currentCodec = pcCodecSettings.codecList[0];
808 850
         const codecScalabilityModeSettings = this.codecSettings[currentCodec];
809 851
 
@@ -846,26 +888,22 @@ export class TPCUtils {
846 888
             }
847 889
         }
848 890
 
849
-        return {
850
-            type: description.type,
851
-            sdp: transform.write(parsedSdp)
852
-        };
891
+        return mungedSdp;
853 892
     }
854 893
 
855 894
     /**
856 895
      * Checks if the AV1 Dependency descriptors are negotiated on the bridge peerconnection and removes them from the
857
-     * description when codec selected is VP8 or VP9.
896
+     * SDP when codec selected is VP8 or VP9.
858 897
      *
859
-     * @param {RTCSessionDescription} description that needs to be munged.
860
-     * @returns {RTCSessionDescription} the munged description.
898
+     * @param {transform.SessionDescription} parsedSdp that needs to be munged.
899
+     * @returns {string} the munged SDP.
861 900
      */
862
-    updateAv1DdHeaders(description) {
863
-        const parsedSdp = transform.parse(description.sdp);
864
-        const mLines = parsedSdp.media.filter(m => m.type === MediaType.VIDEO);
865
-
866
-        if (!mLines.length || !browser.supportsDDExtHeaders()) {
867
-            return description;
901
+    updateAv1DdHeaders(parsedSdp) {
902
+        if (!this.supportsDDHeaderExt) {
903
+            return parsedSdp;
868 904
         }
905
+        const mungedSdp = parsedSdp;
906
+        const mLines = mungedSdp.media.filter(m => m.type === MediaType.VIDEO);
869 907
 
870 908
         mLines.forEach((mLine, idx) => {
871 909
             const senderMids = Array.from(this.pc.localTrackTransceiverMids.values());
@@ -896,9 +934,6 @@ export class TPCUtils {
896 934
             }
897 935
         });
898 936
 
899
-        return {
900
-            type: description.type,
901
-            sdp: transform.write(parsedSdp)
902
-        };
937
+        return mungedSdp;
903 938
     }
904 939
 }

+ 13
- 61
modules/RTC/TraceablePeerConnection.js 파일 보기

@@ -1187,58 +1187,6 @@ TraceablePeerConnection.prototype.getLocalSSRC = function(localTrack) {
1187 1187
     return ssrcInfo && ssrcInfo.ssrcs[0];
1188 1188
 };
1189 1189
 
1190
-/**
1191
- * When doing unified plan simulcast, we'll have a set of ssrcs but no ssrc-groups on Firefox. Unfortunately, Jicofo
1192
- * will complain if it sees ssrcs with matching msids but no ssrc-group, so a ssrc-group line is injected to make
1193
- * Jicofo happy.
1194
- *
1195
- * @param desc A session description object (with 'type' and 'sdp' fields)
1196
- * @return A session description object with its sdp field modified to contain an inject ssrc-group for simulcast.
1197
- */
1198
-TraceablePeerConnection.prototype._injectSsrcGroupForUnifiedSimulcast = function(desc) {
1199
-    const sdp = transform.parse(desc.sdp);
1200
-    const video = sdp.media.find(mline => mline.type === 'video');
1201
-
1202
-    // Check if the browser supports RTX, add only the primary ssrcs to the SIM group if that is the case.
1203
-    video.ssrcGroups = video.ssrcGroups || [];
1204
-    const fidGroups = video.ssrcGroups.filter(group => group.semantics === SSRC_GROUP_SEMANTICS.FID);
1205
-
1206
-    if (video.simulcast || video.simulcast_03) {
1207
-        const ssrcs = [];
1208
-
1209
-        if (fidGroups && fidGroups.length) {
1210
-            fidGroups.forEach(group => {
1211
-                ssrcs.push(group.ssrcs.split(' ')[0]);
1212
-            });
1213
-        } else {
1214
-            video.ssrcs.forEach(ssrc => {
1215
-                if (ssrc.attribute === 'msid') {
1216
-                    ssrcs.push(ssrc.id);
1217
-                }
1218
-            });
1219
-        }
1220
-        if (video.ssrcGroups.find(group => group.semantics === SSRC_GROUP_SEMANTICS.SIM)) {
1221
-            // Group already exists, no need to do anything
1222
-            return desc;
1223
-        }
1224
-
1225
-        // Add a SIM group for every 3 FID groups.
1226
-        for (let i = 0; i < ssrcs.length; i += 3) {
1227
-            const simSsrcs = ssrcs.slice(i, i + 3);
1228
-
1229
-            video.ssrcGroups.push({
1230
-                semantics: SSRC_GROUP_SEMANTICS.SIM,
1231
-                ssrcs: simSsrcs.join(' ')
1232
-            });
1233
-        }
1234
-    }
1235
-
1236
-    return {
1237
-        type: desc.type,
1238
-        sdp: transform.write(sdp)
1239
-    };
1240
-};
1241
-
1242 1190
 /* eslint-disable-next-line vars-on-top */
1243 1191
 const getters = {
1244 1192
     signalingState() {
@@ -1261,9 +1209,8 @@ const getters = {
1261 1209
 
1262 1210
         this.trace('getLocalDescription::preTransform', dumpSDP(desc));
1263 1211
 
1264
-        // For a jvb connection, transform the SDP to Plan B first.
1265 1212
         if (!this.isP2P) {
1266
-            desc = this._injectSsrcGroupForUnifiedSimulcast(desc);
1213
+            desc = this.tpcUtils.injectSsrcGroupForUnifiedSimulcast(desc);
1267 1214
             this.trace('getLocalDescription::postTransform (inject ssrc group)', dumpSDP(desc));
1268 1215
         }
1269 1216
 
@@ -1457,7 +1404,7 @@ TraceablePeerConnection.prototype._assertTrackBelongs = function(
1457 1404
  * @returns {Array}
1458 1405
  */
1459 1406
 TraceablePeerConnection.prototype.getConfiguredVideoCodecs = function(description) {
1460
-    return this.tpcUtils.getConfiguredVideoCodecs(description);
1407
+    return this.tpcUtils.getConfiguredVideoCodecs(description?.sdp);
1461 1408
 };
1462 1409
 
1463 1410
 /**
@@ -2001,13 +1948,18 @@ TraceablePeerConnection.prototype._setEncodings = function(localTrack) {
2001 1948
  * @returns {RTCSessionDescription} - The munged description.
2002 1949
  */
2003 1950
 TraceablePeerConnection.prototype._mungeDescription = function(description) {
2004
-    let mungedDescription = description;
2005
-
2006 1951
     this.trace('RTCSessionDescription::preTransform', dumpSDP(description));
2007
-    mungedDescription = this.tpcUtils.mungeOpus(description);
2008
-    mungedDescription = this.tpcUtils.mungeCodecOrder(mungedDescription);
2009
-    mungedDescription = this.tpcUtils.setMaxBitrates(mungedDescription, true);
2010
-    mungedDescription = this.tpcUtils.updateAv1DdHeaders(mungedDescription);
1952
+    let mungedSdp = transform.parse(description.sdp);
1953
+
1954
+    mungedSdp = this.tpcUtils.mungeOpus(mungedSdp);
1955
+    mungedSdp = this.tpcUtils.mungeCodecOrder(mungedSdp);
1956
+    mungedSdp = this.tpcUtils.setMaxBitrates(mungedSdp, true);
1957
+    mungedSdp = this.tpcUtils.updateAv1DdHeaders(mungedSdp);
1958
+    const mungedDescription = {
1959
+        type: description.type,
1960
+        sdp: transform.write(mungedSdp)
1961
+    };
1962
+
2011 1963
     this.trace('RTCSessionDescription::postTransform', dumpSDP(mungedDescription));
2012 1964
 
2013 1965
     return mungedDescription;

Loading…
취소
저장