~ubuntu-branches/debian/experimental/kopete/experimental

« back to all changes in this revision

Viewing changes to protocols/jabber/googletalk/libjingle/talk/app/webrtc/mediastreamsignaling_unittest.cc

  • Committer: Package Import Robot
  • Author(s): Maximiliano Curia
  • Date: 2015-02-24 11:32:57 UTC
  • mfrom: (1.1.41 vivid)
  • Revision ID: package-import@ubuntu.com-20150224113257-gnupg4v7lzz18ij0
Tags: 4:14.12.2-1
* New upstream release (14.12.2).
* Bump Standards-Version to 3.9.6, no changes needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * libjingle
3
 
 * Copyright 2012, Google Inc.
4
 
 *
5
 
 * Redistribution and use in source and binary forms, with or without
6
 
 * modification, are permitted provided that the following conditions are met:
7
 
 *
8
 
 *  1. Redistributions of source code must retain the above copyright notice,
9
 
 *     this list of conditions and the following disclaimer.
10
 
 *  2. Redistributions in binary form must reproduce the above copyright notice,
11
 
 *     this list of conditions and the following disclaimer in the documentation
12
 
 *     and/or other materials provided with the distribution.
13
 
 *  3. The name of the author may not be used to endorse or promote products
14
 
 *     derived from this software without specific prior written permission.
15
 
 *
16
 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17
 
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18
 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19
 
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
 
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23
 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24
 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25
 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 
 */
27
 
 
28
 
 
29
 
#include <string>
30
 
 
31
 
#include "talk/app/webrtc/audiotrack.h"
32
 
#include "talk/app/webrtc/mediastream.h"
33
 
#include "talk/app/webrtc/mediastreamsignaling.h"
34
 
#include "talk/app/webrtc/streamcollectionimpl.h"
35
 
#include "talk/app/webrtc/videotrack.h"
36
 
#include "talk/base/gunit.h"
37
 
#include "talk/base/scoped_ptr.h"
38
 
#include "talk/base/thread.h"
39
 
#include "talk/p2p/base/constants.h"
40
 
#include "talk/p2p/base/sessiondescription.h"
41
 
 
42
 
static const char kStreams[][8] = {"stream1", "stream2"};
43
 
static const char kAudioTracks[][8] = {"audio_1", "audio_2"};
44
 
static const char kVideoTracks[][8] = {"video_1", "video_2"};
45
 
 
46
 
using webrtc::IceCandidateInterface;
47
 
using webrtc::MediaStreamInterface;
48
 
using webrtc::SessionDescriptionInterface;
49
 
 
50
 
using webrtc::StreamCollection;
51
 
using webrtc::StreamCollectionInterface;
52
 
 
53
 
// Reference SDP with a MediaStream with label "stream1" and audio track with
54
 
// label "audio_1" and a video track with label "video_1;
55
 
static const char kSdpString1[] =
56
 
    "v=0\r\n"
57
 
    "o=- 0 0 IN IP4 127.0.0.1\r\n"
58
 
    "s=\r\n"
59
 
    "t=0 0\r\n"
60
 
    "m=audio 1 RTP/AVPF 103\r\n"
61
 
    "a=mid:audio\r\n"
62
 
    "a=rtpmap:103 ISAC/16000\r\n"
63
 
    "a=ssrc:1 cname:stream1\r\n"
64
 
    "a=ssrc:1 mslabel:stream1\r\n"
65
 
    "a=ssrc:1 label:audio_1\r\n"
66
 
    "m=video 1 RTP/AVPF 120\r\n"
67
 
    "a=mid:video\r\n"
68
 
    "a=rtpmap:120 VP8/90000\r\n"
69
 
    "a=ssrc:2 cname:stream1\r\n"
70
 
    "a=ssrc:2 mslabel:stream1\r\n"
71
 
    "a=ssrc:2 label:video_1\r\n";
72
 
 
73
 
// Reference SDP with two MediaStreams with label "stream1" and "stream2. Each
74
 
// MediaStreams have one audio track and one video track.
75
 
static const char kSdpString2[] =
76
 
    "v=0\r\n"
77
 
    "o=- 0 0 IN IP4 127.0.0.1\r\n"
78
 
    "s=\r\n"
79
 
    "t=0 0\r\n"
80
 
    "m=audio 1 RTP/AVPF 103\r\n"
81
 
    "a=mid:audio\r\n"
82
 
    "a=rtpmap:103 ISAC/16000\r\n"
83
 
    "a=ssrc:1 cname:stream1\r\n"
84
 
    "a=ssrc:1 mslabel:stream1\r\n"
85
 
    "a=ssrc:1 label:audio_1\r\n"
86
 
    "a=ssrc:3 cname:stream2\r\n"
87
 
    "a=ssrc:3 mslabel:stream2\r\n"
88
 
    "a=ssrc:3 label:audio_2\r\n"
89
 
    "m=video 1 RTP/AVPF 120\r\n"
90
 
    "a=mid:video\r\n"
91
 
    "a=rtpmap:120 VP8/0\r\n"
92
 
    "a=ssrc:2 cname:stream1\r\n"
93
 
    "a=ssrc:2 mslabel:stream1\r\n"
94
 
    "a=ssrc:2 label:video_1\r\n"
95
 
    "a=ssrc:4 cname:stream2\r\n"
96
 
    "a=ssrc:4 mslabel:stream2\r\n"
97
 
    "a=ssrc:4 label:video_2\r\n";
98
 
 
99
 
// Create a collection of streams.
100
 
// CreateStreamCollection(1) creates a collection that
101
 
// correspond to kSdpString1.
102
 
// CreateStreamCollection(2) correspond to kSdpString2.
103
 
static talk_base::scoped_refptr<StreamCollection>
104
 
CreateStreamCollection(int number_of_streams) {
105
 
  talk_base::scoped_refptr<StreamCollection> local_collection(
106
 
      StreamCollection::Create());
107
 
 
108
 
  for (int i = 0; i < number_of_streams; ++i) {
109
 
    talk_base::scoped_refptr<webrtc::LocalMediaStreamInterface> stream(
110
 
        webrtc::MediaStream::Create(kStreams[i]));
111
 
 
112
 
    // Add a local audio track.
113
 
    talk_base::scoped_refptr<webrtc::LocalAudioTrackInterface>
114
 
    audio_track(webrtc::AudioTrack::CreateLocal(kAudioTracks[i], NULL));
115
 
    stream->AddTrack(audio_track);
116
 
 
117
 
    // Add a local video track.
118
 
    talk_base::scoped_refptr<webrtc::LocalVideoTrackInterface>
119
 
    video_track(webrtc::VideoTrack::CreateLocal(kVideoTracks[i], NULL));
120
 
    stream->AddTrack(video_track);
121
 
 
122
 
    local_collection->AddStream(stream);
123
 
  }
124
 
  return local_collection;
125
 
}
126
 
 
127
 
// Verifies that |options| contain all tracks in |collection| if |hints| allow
128
 
// them.
129
 
static void VerifyMediaOptions(StreamCollectionInterface* collection,
130
 
                               const webrtc::MediaHints hints,
131
 
                               const cricket::MediaSessionOptions& options) {
132
 
  EXPECT_EQ(hints.has_audio(), options.has_audio);
133
 
  EXPECT_EQ(hints.has_video(), options.has_video);
134
 
 
135
 
  if (!collection)
136
 
    return;
137
 
 
138
 
  size_t stream_index = 0;
139
 
  for (size_t i = 0; i < collection->count(); ++i) {
140
 
    MediaStreamInterface* stream = collection->at(i);
141
 
    ASSERT_GE(options.streams.size(), stream->audio_tracks()->count());
142
 
    for (size_t j = 0; j < stream->audio_tracks()->count(); ++j) {
143
 
      webrtc::AudioTrackInterface* audio = stream->audio_tracks()->at(j);
144
 
      EXPECT_EQ(options.streams[stream_index].sync_label, stream->label());
145
 
      EXPECT_EQ(options.streams[stream_index++].name, audio->label());
146
 
    }
147
 
    ASSERT_GE(options.streams.size(), stream->audio_tracks()->count());
148
 
    for (size_t j = 0; j < stream->video_tracks()->count(); ++j) {
149
 
      webrtc::VideoTrackInterface* video = stream->video_tracks()->at(j);
150
 
      EXPECT_EQ(options.streams[stream_index].sync_label, stream->label());
151
 
      EXPECT_EQ(options.streams[stream_index++].name, video->label());
152
 
    }
153
 
  }
154
 
}
155
 
 
156
 
static bool CompareStreamCollections(StreamCollectionInterface* s1,
157
 
                                     StreamCollectionInterface* s2) {
158
 
  if (s1 == NULL || s2 == NULL || s1->count() != s2->count())
159
 
    return false;
160
 
 
161
 
  for (size_t i = 0; i != s1->count(); ++i) {
162
 
    if (s1->at(i)->label() != s2->at(i)->label())
163
 
      return false;
164
 
    webrtc::AudioTracks* audio_tracks1 = s1->at(i)->audio_tracks();
165
 
    webrtc::AudioTracks* audio_tracks2 = s2->at(i)->audio_tracks();
166
 
    webrtc::VideoTracks* video_tracks1 = s1->at(i)->video_tracks();
167
 
    webrtc::VideoTracks* video_tracks2 = s2->at(i)->video_tracks();
168
 
 
169
 
    if (audio_tracks1->count() != audio_tracks2->count())
170
 
      return false;
171
 
    for (size_t j = 0; j != audio_tracks1->count(); ++j) {
172
 
       if (audio_tracks1->at(j)->label() != audio_tracks2->at(j)->label())
173
 
         return false;
174
 
    }
175
 
    if (video_tracks1->count() != video_tracks2->count())
176
 
      return false;
177
 
    for (size_t j = 0; j != video_tracks1->count(); ++j) {
178
 
       if (video_tracks1->at(j)->label() != video_tracks2->at(j)->label())
179
 
         return false;
180
 
    }
181
 
  }
182
 
  return true;
183
 
}
184
 
 
185
 
// MockRemoteStreamObserver implements functions for listening to
186
 
// callbacks about added and removed remote MediaStreams.
187
 
class MockRemoteStreamObserver : public webrtc::RemoteMediaStreamObserver {
188
 
 public:
189
 
  MockRemoteStreamObserver()
190
 
      : remote_media_streams_(StreamCollection::Create()) {
191
 
  }
192
 
 
193
 
  virtual ~MockRemoteStreamObserver() {
194
 
  }
195
 
 
196
 
  // New remote stream have been discovered.
197
 
  virtual void OnAddStream(MediaStreamInterface* remote_stream) {
198
 
    EXPECT_EQ(MediaStreamInterface::kLive, remote_stream->ready_state());
199
 
    remote_media_streams_->AddStream(remote_stream);
200
 
  }
201
 
 
202
 
  // Remote stream is no longer available.
203
 
  virtual void OnRemoveStream(MediaStreamInterface* remote_stream) {
204
 
    EXPECT_EQ(MediaStreamInterface::kEnded, remote_stream->ready_state());
205
 
    remote_media_streams_->RemoveStream(remote_stream);
206
 
  }
207
 
 
208
 
  MediaStreamInterface* RemoteStream(const std::string& label) {
209
 
    return remote_media_streams_->find(label);
210
 
  }
211
 
 
212
 
  StreamCollectionInterface* remote_streams() const {
213
 
    return remote_media_streams_;
214
 
  }
215
 
 
216
 
 private:
217
 
  talk_base::scoped_refptr<StreamCollection> remote_media_streams_;
218
 
};
219
 
 
220
 
class MediaStreamSignalingForTest : public webrtc::MediaStreamSignaling {
221
 
 public:
222
 
  explicit MediaStreamSignalingForTest(MockRemoteStreamObserver* observer)
223
 
      : webrtc::MediaStreamSignaling(talk_base::Thread::Current(), observer) {
224
 
  };
225
 
  using webrtc::MediaStreamSignaling::SetLocalStreams;
226
 
  using webrtc::MediaStreamSignaling::GetMediaSessionOptions;
227
 
  using webrtc::MediaStreamSignaling::UpdateRemoteStreams;
228
 
  using webrtc::MediaStreamSignaling::remote_streams;
229
 
};
230
 
 
231
 
class MediaStreamSignalingTest: public testing::Test {
232
 
 protected:
233
 
  virtual void SetUp() {
234
 
    observer_.reset(new MockRemoteStreamObserver());
235
 
    signaling_.reset(new MediaStreamSignalingForTest(observer_.get()));
236
 
  }
237
 
 
238
 
  talk_base::scoped_ptr<MockRemoteStreamObserver> observer_;
239
 
  talk_base::scoped_ptr<MediaStreamSignalingForTest> signaling_;
240
 
 
241
 
  void TestGetMediaSessionOptions(const webrtc::MediaHints& hints,
242
 
                                  StreamCollectionInterface* streams) {
243
 
    signaling_->SetLocalStreams(streams);
244
 
    cricket::MediaSessionOptions options =
245
 
        signaling_->GetMediaSessionOptions(hints);
246
 
    VerifyMediaOptions(streams, hints, options);
247
 
  }
248
 
};
249
 
 
250
 
TEST_F(MediaStreamSignalingTest, AudioVideoHints) {
251
 
  webrtc::MediaHints hints;
252
 
  talk_base::scoped_refptr<StreamCollection> local_streams(
253
 
      CreateStreamCollection(1));
254
 
  TestGetMediaSessionOptions(hints, local_streams.get());
255
 
}
256
 
 
257
 
TEST_F(MediaStreamSignalingTest, AudioHints) {
258
 
  webrtc::MediaHints hints(true, false);
259
 
  // Don't use all MediaStreams so we only create offer based on hints without
260
 
  // sending streams.
261
 
  TestGetMediaSessionOptions(hints, NULL);
262
 
}
263
 
 
264
 
TEST_F(MediaStreamSignalingTest, VideoHints) {
265
 
  webrtc::MediaHints hints(false, true);
266
 
  // Don't use all MediaStreams so we only create offer based on hints without
267
 
  // sending streams.
268
 
  TestGetMediaSessionOptions(hints, NULL);
269
 
}
270
 
 
271
 
TEST_F(MediaStreamSignalingTest, UpdateRemoteStreams) {
272
 
  SessionDescriptionInterface* desc = webrtc::CreateSessionDescription(
273
 
      kSdpString1);
274
 
  EXPECT_TRUE(desc != NULL);
275
 
  signaling_->UpdateRemoteStreams(desc);
276
 
 
277
 
  talk_base::scoped_refptr<StreamCollection> reference(
278
 
      CreateStreamCollection(1));
279
 
  EXPECT_TRUE(CompareStreamCollections(signaling_->remote_streams(),
280
 
                                       reference.get()));
281
 
  EXPECT_TRUE(CompareStreamCollections(observer_->remote_streams(),
282
 
                                       reference.get()));
283
 
 
284
 
  // Update the remote streams.
285
 
  SessionDescriptionInterface* update_desc =
286
 
      webrtc::CreateSessionDescription(kSdpString2);
287
 
  EXPECT_TRUE(update_desc != NULL);
288
 
  signaling_->UpdateRemoteStreams(update_desc);
289
 
 
290
 
  talk_base::scoped_refptr<StreamCollection> reference2(
291
 
      CreateStreamCollection(2));
292
 
  EXPECT_TRUE(CompareStreamCollections(signaling_->remote_streams(),
293
 
                                       reference2.get()));
294
 
  EXPECT_TRUE(CompareStreamCollections(observer_->remote_streams(),
295
 
                                       reference2.get()));
296
 
}