Selaa lähdekoodia

Moves add/remove source element creation in strophe.jingle.sdp.js.

j8
George Politis 10 vuotta sitten
vanhempi
commit
f95d5f36bb
2 muutettua tiedostoa jossa 161 lisäystä ja 189 poistoa
  1. 127
    91
      libs/strophe/strophe.jingle.sdp.js
  2. 34
    98
      libs/strophe/strophe.jingle.session.js

+ 127
- 91
libs/strophe/strophe.jingle.sdp.js Näytä tiedosto

@@ -17,27 +17,37 @@ function SDP(sdp) {
17 17
 SDP.prototype.getMediaSsrcMap = function() {
18 18
     var self = this;
19 19
     var media_ssrcs = {};
20
-    for (channelNum = 0; channelNum < self.media.length; channelNum++) {
21
-        modified = true;
22
-        tmp = SDPUtil.find_lines(self.media[channelNum], 'a=ssrc:');
23
-        var type = SDPUtil.parse_mid(SDPUtil.find_line(self.media[channelNum], 'a=mid:'));
24
-        var channel = new MediaChannel(channelNum, type);
25
-        media_ssrcs[channelNum] = channel;
20
+    var tmp;
21
+    for (var mediaindex = 0; mediaindex < self.media.length; mediaindex++) {
22
+        tmp = SDPUtil.find_lines(self.media[mediaindex], 'a=ssrc:');
23
+        var mid = SDPUtil.parse_mid(SDPUtil.find_line(self.media[mediaindex], 'a=mid:'));
24
+        var media = {
25
+            mediaindex: mediaindex,
26
+            mid: mid,
27
+            ssrcs: {},
28
+            ssrcGroups: []
29
+        };
30
+        media_ssrcs[mediaindex] = media;
26 31
         tmp.forEach(function (line) {
27 32
             var linessrc = line.substring(7).split(' ')[0];
28 33
             // allocate new ChannelSsrc
29
-            if(!channel.ssrcs[linessrc]) {
30
-                channel.ssrcs[linessrc] = new ChannelSsrc(linessrc, type);
34
+            if(!media.ssrcs[linessrc]) {
35
+                media.ssrcs[linessrc] = {
36
+                    ssrc: linessrc,
37
+                    lines: []
38
+                };
31 39
             }
32
-            channel.ssrcs[linessrc].lines.push(line);
40
+            media.ssrcs[linessrc].lines.push(line);
33 41
         });
34
-        tmp = SDPUtil.find_lines(self.media[channelNum], 'a=ssrc-group:');
42
+        tmp = SDPUtil.find_lines(self.media[mediaindex], 'a=ssrc-group:');
35 43
         tmp.forEach(function(line){
36 44
             var semantics = line.substr(0, idx).substr(13);
37 45
             var ssrcs = line.substr(14 + semantics.length).split(' ');
38 46
             if (ssrcs.length != 0) {
39
-                var ssrcGroup = new ChannelSsrcGroup(semantics, ssrcs);
40
-                channel.ssrcGroups.push(ssrcGroup);
47
+                media.ssrcGroups.push({
48
+                    semantics: semantics,
49
+                    ssrcs: ssrcs
50
+                });
41 51
             }
42 52
         });
43 53
     }
@@ -49,23 +59,28 @@ SDP.prototype.getMediaSsrcMap = function() {
49 59
  * @returns {boolean} <tt>true</tt> if this SDP contains given SSRC.
50 60
  */
51 61
 SDP.prototype.containsSSRC = function(ssrc) {
52
-    var channels = this.getMediaSsrcMap();
62
+    var medias = this.getMediaSsrcMap();
53 63
     var contains = false;
54
-    Object.keys(channels).forEach(function(chNumber){
55
-        var channel = channels[chNumber];
64
+    Object.keys(medias).forEach(function(mediaindex){
65
+        var media = medias[mediaindex];
56 66
         //console.log("Check", channel, ssrc);
57
-        if(Object.keys(channel.ssrcs).indexOf(ssrc) != -1){
67
+        if(Object.keys(media.ssrcs).indexOf(ssrc) != -1){
58 68
             contains = true;
59 69
         }
60 70
     });
61 71
     return contains;
62 72
 };
63 73
 
74
+function SDPDiffer(mySDP, otherSDP) {
75
+    this.mySDP = new SDP(mySDP);
76
+    this.otherSDP = new SDP(otherSDP);
77
+}
78
+
64 79
 /**
65 80
  * Returns map of MediaChannel that contains only media not contained in <tt>otherSdp</tt>. Mapped by channel idx.
66 81
  * @param otherSdp the other SDP to check ssrc with.
67 82
  */
68
-SDP.prototype.getNewMedia = function(otherSdp) {
83
+SDPDiffer.prototype.getNewMedia = function() {
69 84
 
70 85
     // this could be useful in Array.prototype.
71 86
     function arrayEquals(array) {
@@ -92,35 +107,40 @@ SDP.prototype.getNewMedia = function(otherSdp) {
92 107
         return true;
93 108
     }
94 109
 
95
-    var myMedia = this.getMediaSsrcMap();
96
-    var othersMedia = otherSdp.getMediaSsrcMap();
110
+    var myMedias = this.mySDP.getMediaSsrcMap();
111
+    var othersMedias = this.otherSDP.getMediaSsrcMap();
97 112
     var newMedia = {};
98
-    Object.keys(othersMedia).forEach(function(channelNum) {
99
-        var myChannel = myMedia[channelNum];
100
-        var othersChannel = othersMedia[channelNum];
101
-        if(!myChannel && othersChannel) {
113
+    Object.keys(othersMedias).forEach(function(othersMediaIdx) {
114
+        var myMedia = myMedias[othersMediaIdx];
115
+        var othersMedia = othersMedias[othersMediaIdx];
116
+        if(!myMedia && othersMedia) {
102 117
             // Add whole channel
103
-            newMedia[channelNum] = othersChannel;
118
+            newMedia[othersMediaIdx] = othersMedia;
104 119
             return;
105 120
         }
106 121
         // Look for new ssrcs accross the channel
107
-        Object.keys(othersChannel.ssrcs).forEach(function(ssrc) {
108
-            if(Object.keys(myChannel.ssrcs).indexOf(ssrc) === -1) {
122
+        Object.keys(othersMedia.ssrcs).forEach(function(ssrc) {
123
+            if(Object.keys(myMedia.ssrcs).indexOf(ssrc) === -1) {
109 124
                 // Allocate channel if we've found ssrc that doesn't exist in our channel
110
-                if(!newMedia[channelNum]){
111
-                    newMedia[channelNum] = new MediaChannel(othersChannel.chNumber, othersChannel.mediaType);
125
+                if(!newMedia[othersMediaIdx]){
126
+                    newMedia[othersMediaIdx] = {
127
+                        mediaindex: othersMedia.mediaindex,
128
+                        mid: othersMedia.mid,
129
+                        ssrcs: {},
130
+                        ssrcGroups: []
131
+                    };
112 132
                 }
113
-                newMedia[channelNum].ssrcs[ssrc] = othersChannel.ssrcs[ssrc];
133
+                newMedia[othersMediaIdx].ssrcs[ssrc] = othersMedia.ssrcs[ssrc];
114 134
             }
115 135
         });
116 136
 
117 137
         // Look for new ssrc groups across the channels
118
-        othersChannel.ssrcGroups.forEach(function(otherSsrcGroup){
138
+        othersMedia.ssrcGroups.forEach(function(otherSsrcGroup){
119 139
 
120 140
             // try to match the other ssrc-group with an ssrc-group of ours
121 141
             var matched = false;
122
-            for (var i = 0; i < myChannel.ssrcGroups.length; i++) {
123
-                var mySsrcGroup = myChannel.ssrcGroups[i];
142
+            for (var i = 0; i < myMedia.ssrcGroups.length; i++) {
143
+                var mySsrcGroup = myMedia.ssrcGroups[i];
124 144
                 if (otherSsrcGroup.semantics == mySsrcGroup.semantics
125 145
                     && arrayEquals.apply(otherSsrcGroup.ssrcs, [mySsrcGroup.ssrcs])) {
126 146
 
@@ -133,16 +153,88 @@ SDP.prototype.getNewMedia = function(otherSdp) {
133 153
                 // Allocate channel if we've found an ssrc-group that doesn't
134 154
                 // exist in our channel
135 155
 
136
-                if(!newMedia[channelNum]){
137
-                    newMedia[channelNum] = new MediaChannel(othersChannel.chNumber, othersChannel.mediaType);
156
+                if(!newMedia[othersMediaIdx]){
157
+                    newMedia[othersMediaIdx] = {
158
+                        mediaindex: othersMedia.mediaindex,
159
+                        mid: othersMedia.mid,
160
+                        ssrcs: {},
161
+                        ssrcGroups: []
162
+                    };
138 163
                 }
139
-                newMedia[channelNum].ssrcGroups.push(otherSsrcGroup);
164
+                newMedia[othersMediaIdx].ssrcGroups.push(otherSsrcGroup);
140 165
             }
141 166
         });
142 167
     });
143 168
     return newMedia;
144 169
 };
145 170
 
171
+/**
172
+ * Sends SSRC update IQ.
173
+ * @param sdpMediaSsrcs SSRCs map obtained from SDP.getNewMedia. Cntains SSRCs to add/remove.
174
+ * @param sid session identifier that will be put into the IQ.
175
+ * @param initiator initiator identifier.
176
+ * @param toJid destination Jid
177
+ * @param isAdd indicates if this is remove or add operation.
178
+ */
179
+SDPDiffer.prototype.toJingle = function(modify) {
180
+    var sdpMediaSsrcs = this.getNewMedia();
181
+    var self = this;
182
+
183
+    // FIXME: only announce video ssrcs since we mix audio and dont need
184
+    //      the audio ssrcs therefore
185
+    var modified = false;
186
+    Object.keys(sdpMediaSsrcs).forEach(function(mediaindex){
187
+        modified = true;
188
+        var media = sdpMediaSsrcs[mediaindex];
189
+        modify.c('content', {name: media.mid});
190
+
191
+        modify.c('description', {xmlns:'urn:xmpp:jingle:apps:rtp:1', media: media.mid});
192
+        // FIXME: not completly sure this operates on blocks and / or handles different ssrcs correctly
193
+        // generate sources from lines
194
+        Object.keys(media.ssrcs).forEach(function(ssrcNum) {
195
+            var mediaSsrc = media.ssrcs[ssrcNum];
196
+            modify.c('source', { xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0' });
197
+            modify.attrs({ssrc: mediaSsrc.ssrc});
198
+            // iterate over ssrc lines
199
+            mediaSsrc.lines.forEach(function (line) {
200
+                var idx = line.indexOf(' ');
201
+                var kv = line.substr(idx + 1);
202
+                modify.c('parameter');
203
+                if (kv.indexOf(':') == -1) {
204
+                    modify.attrs({ name: kv });
205
+                } else {
206
+                    modify.attrs({ name: kv.split(':', 2)[0] });
207
+                    modify.attrs({ value: kv.split(':', 2)[1] });
208
+                }
209
+                modify.up(); // end of parameter
210
+            });
211
+            modify.up(); // end of source
212
+        });
213
+
214
+        // generate source groups from lines
215
+        media.ssrcGroups.forEach(function(ssrcGroup) {
216
+            if (ssrcGroup.ssrcs.length != 0) {
217
+
218
+                modify.c('ssrc-group', {
219
+                    semantics: ssrcGroup.semantics,
220
+                    xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0'
221
+                });
222
+
223
+                ssrcGroup.ssrcs.forEach(function (ssrc) {
224
+                    modify.c('source', { ssrc: ssrc })
225
+                        .up(); // end of source
226
+                });
227
+                modify.up(); // end of ssrc-group
228
+            }
229
+        });
230
+
231
+        modify.up(); // end of description
232
+        modify.up(); // end of content
233
+    });
234
+
235
+    return modified;
236
+};
237
+
146 238
 // remove iSAC and CN from SDP
147 239
 SDP.prototype.mangle = function () {
148 240
     var i, j, mline, lines, rtpmap, newdesc;
@@ -683,62 +775,6 @@ SDP.prototype.jingle2media = function (content) {
683 775
 
684 776
     return media;
685 777
 };
686
-/**
687
- * Contains utility classes used in SDP class.
688
- *
689
- */
690
-
691
-/**
692
- * Class holds a=ssrc lines and media type a=mid
693
- * @param ssrc synchronization source identifier number(a=ssrc lines from SDP)
694
- * @param type media type eg. "audio" or "video"(a=mid frm SDP)
695
- * @constructor
696
- */
697
-function ChannelSsrc(ssrc, type) {
698
-    this.ssrc = ssrc;
699
-    this.type = type;
700
-    this.lines = [];
701
-}
702
-
703
-/**
704
- * Class holds a=ssrc-group: lines
705
- * @param semantics
706
- * @param ssrcs
707
- * @constructor
708
- */
709
-function ChannelSsrcGroup(semantics, ssrcs, line) {
710
-    this.semantics = semantics;
711
-    this.ssrcs = ssrcs;
712
-}
713
-
714
-/**
715
- * Helper class represents media channel. Is a container for ChannelSsrc, holds channel idx and media type.
716
- * @param channelNumber channel idx in SDP media array.
717
- * @param mediaType media type(a=mid)
718
- * @constructor
719
- */
720
-function MediaChannel(channelNumber, mediaType) {
721
-    /**
722
-     * SDP channel number
723
-     * @type {*}
724
-     */
725
-    this.chNumber = channelNumber;
726
-    /**
727
-     * Channel media type(a=mid)
728
-     * @type {*}
729
-     */
730
-    this.mediaType = mediaType;
731
-    /**
732
-     * The maps of ssrc numbers to ChannelSsrc objects.
733
-     */
734
-    this.ssrcs = {};
735
-
736
-    /**
737
-     * The array of ChannelSsrcGroup objects.
738
-     * @type {Array}
739
-     */
740
-    this.ssrcGroups = [];
741
-}
742 778
 
743 779
 SDPUtil = {
744 780
     iceparams: function (mediadesc, sessiondesc) {

+ 34
- 98
libs/strophe/strophe.jingle.session.js Näytä tiedosto

@@ -968,121 +968,57 @@ JingleSession.prototype.switchStreams = function (new_stream, oldStream, success
968 968
  */
969 969
 JingleSession.prototype.notifyMySSRCUpdate = function (old_sdp, new_sdp) {
970 970
 
971
-    var old_media = old_sdp.getMediaSsrcMap();
972
-    var new_media = new_sdp.getMediaSsrcMap();
973
-    //console.log("old/new medias: ", old_media, new_media);
974
-
975
-    var toAdd = old_sdp.getNewMedia(new_sdp);
976
-    var toRemove = new_sdp.getNewMedia(old_sdp);
977
-    //console.log("to add", toAdd);
978
-    //console.log("to remove", toRemove);
979
-    if(Object.keys(toRemove).length > 0){
980
-        this.sendSSRCUpdate(toRemove, null, false);
981
-    }
982
-    if(Object.keys(toAdd).length > 0){
983
-        this.sendSSRCUpdate(toAdd, null, true);
984
-    }
985
-};
986
-
987
-/**
988
- * Empty method that does nothing by default. It should send SSRC update IQs to session participants.
989
- * @param sdpMediaSsrcs array of
990
- * @param fromJid
991
- * @param isAdd
992
- */
993
-JingleSession.prototype.sendSSRCUpdate = function(sdpMediaSsrcs, fromJid, isAdd) {
994
-    var self = this;
995
-    console.log('tell', self.peerjid, 'about ' + (isadd ? 'new' : 'removed') + ' ssrcs from' + self.me);
996
-
997 971
     if (!(this.peerconnection.signalingState == 'stable' && this.peerconnection.iceConnectionState == 'connected')){
998 972
         console.log("Too early to send updates");
999 973
         return;
1000 974
     }
1001 975
 
1002
-    this.sendSSRCUpdateIq(sdpMediaSsrcs, self.sid, self.initiator, self.peerjid, isadd);
1003
-}
1004
-
1005
-/**
1006
- * Sends SSRC update IQ.
1007
- * @param sdpMediaSsrcs SSRCs map obtained from SDP.getNewMedia. Cntains SSRCs to add/remove.
1008
- * @param sid session identifier that will be put into the IQ.
1009
- * @param initiator initiator identifier.
1010
- * @param toJid destination Jid
1011
- * @param isAdd indicates if this is remove or add operation.
1012
- */
1013
-JingleSession.prototype.sendSSRCUpdateIq = function(sdpMediaSsrcs, sid, initiator, toJid, isAdd) {
1014
-
1015
-    var self = this;
1016
-    var modify = $iq({to: toJid, type: 'set'})
976
+    // send source-add IQ.
977
+    var sdpDiffer = new SDPDiffer(old_sdp, new_sdp);
978
+    var add = $iq({to: self.peerjid, type: 'set'})
1017 979
         .c('jingle', {
1018 980
             xmlns: 'urn:xmpp:jingle:1',
1019
-            action: isAdd ? 'source-add' : 'source-remove',
1020
-            initiator: initiator,
1021
-            sid: sid
981
+            action: 'source-add',
982
+            initiator: self.initiator,
983
+            sid: self.sid
1022 984
         }
1023 985
     );
1024
-    // FIXME: only announce video ssrcs since we mix audio and dont need
1025
-    //      the audio ssrcs therefore
1026
-    var modified = false;
1027
-    Object.keys(sdpMediaSsrcs).forEach(function(channelNum){
1028
-        modified = true;
1029
-        var channel = sdpMediaSsrcs[channelNum];
1030
-        modify.c('content', {name: channel.mediaType});
1031
-
1032
-        modify.c('description', {xmlns:'urn:xmpp:jingle:apps:rtp:1', media: channel.mediaType});
1033
-        // FIXME: not completly sure this operates on blocks and / or handles different ssrcs correctly
1034
-        // generate sources from lines
1035
-        Object.keys(channel.ssrcs).forEach(function(ssrcNum) {
1036
-            var mediaSsrc = channel.ssrcs[ssrcNum];
1037
-            modify.c('source', { xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0' });
1038
-            modify.attrs({ssrc: mediaSsrc.ssrc});
1039
-            // iterate over ssrc lines
1040
-            mediaSsrc.lines.forEach(function (line) {
1041
-                var idx = line.indexOf(' ');
1042
-                var kv = line.substr(idx + 1);
1043
-                modify.c('parameter');
1044
-                if (kv.indexOf(':') == -1) {
1045
-                    modify.attrs({ name: kv });
1046
-                } else {
1047
-                    modify.attrs({ name: kv.split(':', 2)[0] });
1048
-                    modify.attrs({ value: kv.split(':', 2)[1] });
1049
-                }
1050
-                modify.up(); // end of parameter
1051
-            });
1052
-            modify.up(); // end of source
1053
-        });
1054
-
1055
-        // generate source groups from lines
1056
-        channel.ssrcGroups.forEach(function(ssrcGroup) {
1057
-            if (ssrcGroup.ssrcs.length != 0) {
1058
-
1059
-                modify.c('ssrc-group', {
1060
-                    semantics: ssrcGroup.semantics,
1061
-                    xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0'
1062
-                });
1063
-
1064
-                ssrcGroup.ssrcs.forEach(function (ssrc) {
1065
-                    modify.c('source', { ssrc: ssrc })
1066
-                        .up(); // end of source
1067
-                });
1068
-                modify.up(); // end of ssrc-group
986
+    var added = sdpDiffer.toJingle(add);
987
+    if (added) {
988
+        this.connection.sendIQ(add,
989
+            function (res) {
990
+                console.info('got add result', res);
991
+            },
992
+            function (err) {
993
+                console.error('got add error', err);
1069 994
             }
1070
-        });
995
+        );
996
+    } else {
997
+        console.log('addition not necessary');
998
+    }
1071 999
 
1072
-        modify.up(); // end of description
1073
-        modify.up(); // end of content
1074
-    });
1075
-    if (modified) {
1076
-        self.connection.sendIQ(modify,
1000
+    // send source-remove IQ.
1001
+    sdpDiffer = new SDPDiffer(new_sdp, old_sdp);
1002
+    var remove = $iq({to: self.peerjid, type: 'set'})
1003
+        .c('jingle', {
1004
+            xmlns: 'urn:xmpp:jingle:1',
1005
+            action: 'source-remove',
1006
+            initiator: self.initiator,
1007
+            sid: self.sid
1008
+        }
1009
+    );
1010
+    var removed = sdpDiffer.toJingle(remove);
1011
+    if (removed) {
1012
+        this.connection.sendIQ(remove,
1077 1013
             function (res) {
1078
-                console.info('got modify result', res);
1014
+                console.info('got remove result', res);
1079 1015
             },
1080 1016
             function (err) {
1081
-                console.error('got modify error', err);
1017
+                console.error('got remove error', err);
1082 1018
             }
1083 1019
         );
1084 1020
     } else {
1085
-        console.log('modification not necessary');
1021
+        console.log('removal not necessary');
1086 1022
     }
1087 1023
 };
1088 1024
 

Loading…
Peruuta
Tallenna