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

« back to all changes in this revision

Viewing changes to protocols/jabber/libjingle/talk/session/phone/mediasession_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 2004--2011, 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
#include <string>
 
29
#include <vector>
 
30
 
 
31
#include "talk/base/gunit.h"
 
32
#include "talk/p2p/base/constants.h"
 
33
#include "talk/session/phone/codec.h"
 
34
#include "talk/session/phone/mediasession.h"
 
35
#include "talk/session/phone/srtpfilter.h"
 
36
#include "talk/session/phone/testutils.h"
 
37
 
 
38
#ifdef HAVE_SRTP
 
39
#define ASSERT_CRYPTO(cd, r, s, cs) \
 
40
    ASSERT_EQ(r, cd->crypto_required()); \
 
41
    ASSERT_EQ(s, cd->cryptos().size()); \
 
42
    ASSERT_EQ(std::string(cs), cd->cryptos()[0].cipher_suite)
 
43
#else
 
44
#define ASSERT_CRYPTO(c, r, s, cs) \
 
45
  ASSERT_EQ(false, cd->crypto_required()); \
 
46
  ASSERT_EQ(0U, cd->cryptos().size());
 
47
#endif
 
48
 
 
49
using cricket::MediaSessionDescriptionFactory;
 
50
using cricket::MediaSessionOptions;
 
51
using cricket::MediaType;
 
52
using cricket::SessionDescription;
 
53
using cricket::SsrcGroup;
 
54
using cricket::StreamParams;
 
55
using cricket::StreamParamsVec;
 
56
using cricket::ContentInfo;
 
57
using cricket::CryptoParamsVec;
 
58
using cricket::AudioContentDescription;
 
59
using cricket::VideoContentDescription;
 
60
using cricket::DataContentDescription;
 
61
using cricket::GetFirstAudioContentDescription;
 
62
using cricket::GetFirstVideoContentDescription;
 
63
using cricket::GetFirstDataContentDescription;
 
64
using cricket::kAutoBandwidth;
 
65
using cricket::AudioCodec;
 
66
using cricket::VideoCodec;
 
67
using cricket::DataCodec;
 
68
using cricket::NS_JINGLE_RTP;
 
69
using cricket::MEDIA_TYPE_AUDIO;
 
70
using cricket::MEDIA_TYPE_VIDEO;
 
71
using cricket::MEDIA_TYPE_DATA;
 
72
using cricket::SEC_ENABLED;
 
73
using cricket::CS_AES_CM_128_HMAC_SHA1_32;
 
74
using cricket::CS_AES_CM_128_HMAC_SHA1_80;
 
75
 
 
76
static const AudioCodec kAudioCodecs1[] = {
 
77
  AudioCodec(103, "ISAC",   16000, -1,    1, 5),
 
78
  AudioCodec(102, "iLBC",   8000,  13300, 1, 4),
 
79
  AudioCodec(0,   "PCMU",   8000,  64000, 1, 3),
 
80
  AudioCodec(8,   "PCMA",   8000,  64000, 1, 2),
 
81
  AudioCodec(117, "red",    8000,  0,     1, 1),
 
82
};
 
83
 
 
84
static const AudioCodec kAudioCodecs2[] = {
 
85
  AudioCodec(126, "speex",  16000, 22000, 1, 3),
 
86
  AudioCodec(127, "iLBC",   8000,  13300, 1, 2),
 
87
  AudioCodec(0,   "PCMU",   8000,  64000, 1, 1),
 
88
};
 
89
 
 
90
static const AudioCodec kAudioCodecsAnswer[] = {
 
91
  AudioCodec(102, "iLBC",   8000,  13300, 1, 2),
 
92
  AudioCodec(0,   "PCMU",   8000,  64000, 1, 1),
 
93
};
 
94
 
 
95
static const VideoCodec kVideoCodecs1[] = {
 
96
  VideoCodec(96, "H264-SVC", 320, 200, 30, 2),
 
97
  VideoCodec(97, "H264", 320, 200, 30, 1)
 
98
};
 
99
 
 
100
static const VideoCodec kVideoCodecs2[] = {
 
101
  VideoCodec(126, "H264", 320, 200, 30, 2),
 
102
  VideoCodec(127, "H263", 320, 200, 30, 1)
 
103
};
 
104
 
 
105
static const VideoCodec kVideoCodecsAnswer[] = {
 
106
  VideoCodec(97, "H264", 320, 200, 30, 2)
 
107
};
 
108
 
 
109
static const DataCodec kDataCodecs1[] = {
 
110
  DataCodec(96, "binary-data", 2),
 
111
  DataCodec(97, "utf8-text", 1)
 
112
};
 
113
 
 
114
static const DataCodec kDataCodecs2[] = {
 
115
  DataCodec(126, "binary-data", 2),
 
116
  DataCodec(127, "utf8-text", 1)
 
117
};
 
118
 
 
119
static const DataCodec kDataCodecsAnswer[] = {
 
120
  DataCodec(96, "binary-data", 2),
 
121
  DataCodec(97, "utf8-text", 1)
 
122
};
 
123
 
 
124
static const uint32 kSimulcastParamsSsrc[] = {10, 11, 20, 21, 30, 31};
 
125
static const uint32 kSimSsrc[] = {10, 20, 30};
 
126
static const uint32 kFec1Ssrc[] = {10, 11};
 
127
static const uint32 kFec2Ssrc[] = {20, 21};
 
128
static const uint32 kFec3Ssrc[] = {30, 31};
 
129
 
 
130
static const char kMediaStream1[] = "stream_1";
 
131
static const char kMediaStream2[] = "stream_2";
 
132
static const char kVideoTrack1[] = "video_1";
 
133
static const char kVideoTrack2[] = "video_2";
 
134
static const char kAudioTrack1[] = "audio_1";
 
135
static const char kAudioTrack2[] = "audio_2";
 
136
static const char kAudioTrack3[] = "audio_3";
 
137
static const char kDataTrack1[] = "data_1";
 
138
static const char kDataTrack2[] = "data_2";
 
139
static const char kDataTrack3[] = "data_3";
 
140
 
 
141
class MediaSessionDescriptionFactoryTest : public testing::Test {
 
142
 public:
 
143
  MediaSessionDescriptionFactoryTest() {
 
144
    f1_.set_audio_codecs(MAKE_VECTOR(kAudioCodecs1));
 
145
    f1_.set_video_codecs(MAKE_VECTOR(kVideoCodecs1));
 
146
    f1_.set_data_codecs(MAKE_VECTOR(kDataCodecs1));
 
147
    f2_.set_audio_codecs(MAKE_VECTOR(kAudioCodecs2));
 
148
    f2_.set_video_codecs(MAKE_VECTOR(kVideoCodecs2));
 
149
    f2_.set_data_codecs(MAKE_VECTOR(kDataCodecs2));
 
150
  }
 
151
 
 
152
  // Create a video StreamParamsVec object with:
 
153
  // - one video stream with 3 simulcast streams and FEC,
 
154
  StreamParamsVec CreateComplexVideoStreamParamsVec() {
 
155
    SsrcGroup sim_group("SIM", MAKE_VECTOR(kSimSsrc));
 
156
    SsrcGroup fec_group1("FEC", MAKE_VECTOR(kFec1Ssrc));
 
157
    SsrcGroup fec_group2("FEC", MAKE_VECTOR(kFec2Ssrc));
 
158
    SsrcGroup fec_group3("FEC", MAKE_VECTOR(kFec3Ssrc));
 
159
 
 
160
    std::vector<SsrcGroup> ssrc_groups;
 
161
    ssrc_groups.push_back(sim_group);
 
162
    ssrc_groups.push_back(fec_group1);
 
163
    ssrc_groups.push_back(fec_group2);
 
164
    ssrc_groups.push_back(fec_group3);
 
165
 
 
166
    StreamParams simulcast_params;
 
167
    simulcast_params.name = kVideoTrack1;
 
168
    simulcast_params.ssrcs = MAKE_VECTOR(kSimulcastParamsSsrc);
 
169
    simulcast_params.ssrc_groups = ssrc_groups;
 
170
    simulcast_params.cname = "Video_SIM_FEC";
 
171
    simulcast_params.sync_label = kMediaStream1;
 
172
 
 
173
    StreamParamsVec video_streams;
 
174
    video_streams.push_back(simulcast_params);
 
175
 
 
176
    return video_streams;
 
177
  }
 
178
  bool CompareCryptoParams(const CryptoParamsVec& c1,
 
179
                           const CryptoParamsVec& c2) {
 
180
    if (c1.size() != c2.size())
 
181
      return false;
 
182
    for (size_t i = 0; i < c1.size(); ++i)
 
183
      if (c1[i].tag != c2[i].tag || c1[i].cipher_suite != c2[i].cipher_suite ||
 
184
          c1[i].key_params != c2[i].key_params ||
 
185
          c1[i].session_params != c2[i].session_params)
 
186
        return false;
 
187
    return true;
 
188
  }
 
189
 
 
190
 protected:
 
191
  MediaSessionDescriptionFactory f1_;
 
192
  MediaSessionDescriptionFactory f2_;
 
193
};
 
194
 
 
195
// Create a typical audio offer, and ensure it matches what we expect.
 
196
TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOffer) {
 
197
  f1_.set_secure(SEC_ENABLED);
 
198
  talk_base::scoped_ptr<SessionDescription> offer(
 
199
      f1_.CreateOffer(MediaSessionOptions(), NULL));
 
200
  ASSERT_TRUE(offer.get() != NULL);
 
201
  const ContentInfo* ac = offer->GetContentByName("audio");
 
202
  const ContentInfo* vc = offer->GetContentByName("video");
 
203
  ASSERT_TRUE(ac != NULL);
 
204
  ASSERT_TRUE(vc == NULL);
 
205
  EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type);
 
206
  const AudioContentDescription* acd =
 
207
      static_cast<const AudioContentDescription*>(ac->description);
 
208
  EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
 
209
  EXPECT_EQ(f1_.audio_codecs(), acd->codecs());
 
210
  EXPECT_NE(0U, acd->first_ssrc());             // a random nonzero ssrc
 
211
  EXPECT_EQ(kAutoBandwidth, acd->bandwidth());  // default bandwidth (auto)
 
212
  EXPECT_TRUE(acd->rtcp_mux());                 // rtcp-mux defaults on
 
213
  ASSERT_CRYPTO(acd, false, 2U, CS_AES_CM_128_HMAC_SHA1_32);
 
214
}
 
215
 
 
216
// Create a typical video offer, and ensure it matches what we expect.
 
217
TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoOffer) {
 
218
  MediaSessionOptions opts;
 
219
  opts.has_video = true;
 
220
  f1_.set_secure(SEC_ENABLED);
 
221
  talk_base::scoped_ptr<SessionDescription>
 
222
      offer(f1_.CreateOffer(opts, NULL));
 
223
  ASSERT_TRUE(offer.get() != NULL);
 
224
  const ContentInfo* ac = offer->GetContentByName("audio");
 
225
  const ContentInfo* vc = offer->GetContentByName("video");
 
226
  ASSERT_TRUE(ac != NULL);
 
227
  ASSERT_TRUE(vc != NULL);
 
228
  EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type);
 
229
  EXPECT_EQ(std::string(NS_JINGLE_RTP), vc->type);
 
230
  const AudioContentDescription* acd =
 
231
      static_cast<const AudioContentDescription*>(ac->description);
 
232
  const VideoContentDescription* vcd =
 
233
      static_cast<const VideoContentDescription*>(vc->description);
 
234
  EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
 
235
  EXPECT_EQ(f1_.audio_codecs(), acd->codecs());
 
236
  EXPECT_NE(0U, acd->first_ssrc());             // a random nonzero ssrc
 
237
  EXPECT_EQ(kAutoBandwidth, acd->bandwidth());  // default bandwidth (auto)
 
238
  EXPECT_TRUE(acd->rtcp_mux());                 // rtcp-mux defaults on
 
239
  ASSERT_CRYPTO(acd, false, 2U, CS_AES_CM_128_HMAC_SHA1_32);
 
240
  EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type());
 
241
  EXPECT_EQ(f1_.video_codecs(), vcd->codecs());
 
242
  EXPECT_NE(0U, vcd->first_ssrc());             // a random nonzero ssrc
 
243
  EXPECT_EQ(kAutoBandwidth, vcd->bandwidth());  // default bandwidth (auto)
 
244
  EXPECT_TRUE(vcd->rtcp_mux());                 // rtcp-mux defaults on
 
245
  ASSERT_CRYPTO(vcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
 
246
}
 
247
 
 
248
// Create a typical data offer, and ensure it matches what we expect.
 
249
TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataOffer) {
 
250
  MediaSessionOptions opts;
 
251
  opts.has_data = true;
 
252
  f1_.set_secure(SEC_ENABLED);
 
253
  talk_base::scoped_ptr<SessionDescription>
 
254
      offer(f1_.CreateOffer(opts, NULL));
 
255
  ASSERT_TRUE(offer.get() != NULL);
 
256
  const ContentInfo* ac = offer->GetContentByName("audio");
 
257
  const ContentInfo* dc = offer->GetContentByName("data");
 
258
  ASSERT_TRUE(ac != NULL);
 
259
  ASSERT_TRUE(dc != NULL);
 
260
  EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type);
 
261
  EXPECT_EQ(std::string(NS_JINGLE_RTP), dc->type);
 
262
  const AudioContentDescription* acd =
 
263
      static_cast<const AudioContentDescription*>(ac->description);
 
264
  const DataContentDescription* dcd =
 
265
      static_cast<const DataContentDescription*>(dc->description);
 
266
  EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
 
267
  EXPECT_EQ(f1_.audio_codecs(), acd->codecs());
 
268
  EXPECT_NE(0U, acd->first_ssrc());             // a random nonzero ssrc
 
269
  EXPECT_EQ(kAutoBandwidth, acd->bandwidth());  // default bandwidth (auto)
 
270
  EXPECT_TRUE(acd->rtcp_mux());                 // rtcp-mux defaults on
 
271
  ASSERT_CRYPTO(acd, false, 2U, CS_AES_CM_128_HMAC_SHA1_32);
 
272
  EXPECT_EQ(MEDIA_TYPE_DATA, dcd->type());
 
273
  EXPECT_EQ(f1_.data_codecs(), dcd->codecs());
 
274
  EXPECT_NE(0U, dcd->first_ssrc());             // a random nonzero ssrc
 
275
  EXPECT_EQ(cricket::kDataMaxBandwidth,
 
276
            dcd->bandwidth());                  // default bandwidth (auto)
 
277
  EXPECT_TRUE(dcd->rtcp_mux());                 // rtcp-mux defaults on
 
278
  ASSERT_CRYPTO(dcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
 
279
}
 
280
 
 
281
// Create an audio, video offer without legacy StreamParams.
 
282
TEST_F(MediaSessionDescriptionFactoryTest,
 
283
       TestCreateOfferWithoutLegacyStreams) {
 
284
  MediaSessionOptions opts;
 
285
  opts.has_video = true;
 
286
  f1_.set_add_legacy_streams(false);
 
287
  talk_base::scoped_ptr<SessionDescription>
 
288
      offer(f1_.CreateOffer(opts, NULL));
 
289
  ASSERT_TRUE(offer.get() != NULL);
 
290
  const ContentInfo* ac = offer->GetContentByName("audio");
 
291
  const ContentInfo* vc = offer->GetContentByName("video");
 
292
  ASSERT_TRUE(ac != NULL);
 
293
  ASSERT_TRUE(vc != NULL);
 
294
  const AudioContentDescription* acd =
 
295
      static_cast<const AudioContentDescription*>(ac->description);
 
296
  const VideoContentDescription* vcd =
 
297
      static_cast<const VideoContentDescription*>(vc->description);
 
298
 
 
299
  EXPECT_FALSE(vcd->has_ssrcs());             // No StreamParams.
 
300
  EXPECT_FALSE(acd->has_ssrcs());             // No StreamParams.
 
301
}
 
302
 
 
303
// Create a typical audio answer, and ensure it matches what we expect.
 
304
TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswer) {
 
305
  f1_.set_secure(SEC_ENABLED);
 
306
  f2_.set_secure(SEC_ENABLED);
 
307
  talk_base::scoped_ptr<SessionDescription> offer(
 
308
      f1_.CreateOffer(MediaSessionOptions(), NULL));
 
309
  ASSERT_TRUE(offer.get() != NULL);
 
310
  talk_base::scoped_ptr<SessionDescription> answer(
 
311
      f2_.CreateAnswer(offer.get(), MediaSessionOptions(), NULL));
 
312
  const ContentInfo* ac = answer->GetContentByName("audio");
 
313
  const ContentInfo* vc = answer->GetContentByName("video");
 
314
  ASSERT_TRUE(ac != NULL);
 
315
  ASSERT_TRUE(vc == NULL);
 
316
  EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type);
 
317
  const AudioContentDescription* acd =
 
318
      static_cast<const AudioContentDescription*>(ac->description);
 
319
  EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
 
320
  EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs());
 
321
  EXPECT_NE(0U, acd->first_ssrc());             // a random nonzero ssrc
 
322
  EXPECT_EQ(kAutoBandwidth, acd->bandwidth());  // negotiated auto bw
 
323
  EXPECT_TRUE(acd->rtcp_mux());                 // negotiated rtcp-mux
 
324
  ASSERT_CRYPTO(acd, false, 1U, CS_AES_CM_128_HMAC_SHA1_32);
 
325
}
 
326
 
 
327
// Create a typical video answer, and ensure it matches what we expect.
 
328
TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswer) {
 
329
  MediaSessionOptions opts;
 
330
  opts.has_video = true;
 
331
  f1_.set_secure(SEC_ENABLED);
 
332
  f2_.set_secure(SEC_ENABLED);
 
333
  talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
 
334
  ASSERT_TRUE(offer.get() != NULL);
 
335
  talk_base::scoped_ptr<SessionDescription> answer(
 
336
      f2_.CreateAnswer(offer.get(), opts, NULL));
 
337
  const ContentInfo* ac = answer->GetContentByName("audio");
 
338
  const ContentInfo* vc = answer->GetContentByName("video");
 
339
  ASSERT_TRUE(ac != NULL);
 
340
  ASSERT_TRUE(vc != NULL);
 
341
  EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type);
 
342
  EXPECT_EQ(std::string(NS_JINGLE_RTP), vc->type);
 
343
  const AudioContentDescription* acd =
 
344
      static_cast<const AudioContentDescription*>(ac->description);
 
345
  const VideoContentDescription* vcd =
 
346
      static_cast<const VideoContentDescription*>(vc->description);
 
347
  EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
 
348
  EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs());
 
349
  EXPECT_EQ(kAutoBandwidth, acd->bandwidth());  // negotiated auto bw
 
350
  EXPECT_NE(0U, acd->first_ssrc());             // a random nonzero ssrc
 
351
  EXPECT_TRUE(acd->rtcp_mux());                 // negotiated rtcp-mux
 
352
  ASSERT_CRYPTO(acd, false, 1U, CS_AES_CM_128_HMAC_SHA1_32);
 
353
  EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type());
 
354
  EXPECT_EQ(MAKE_VECTOR(kVideoCodecsAnswer), vcd->codecs());
 
355
  EXPECT_NE(0U, vcd->first_ssrc());             // a random nonzero ssrc
 
356
  EXPECT_TRUE(vcd->rtcp_mux());                 // negotiated rtcp-mux
 
357
  ASSERT_CRYPTO(vcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
 
358
}
 
359
 
 
360
TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswer) {
 
361
  MediaSessionOptions opts;
 
362
  opts.has_data = true;
 
363
  f1_.set_secure(SEC_ENABLED);
 
364
  f2_.set_secure(SEC_ENABLED);
 
365
  talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
 
366
  ASSERT_TRUE(offer.get() != NULL);
 
367
  talk_base::scoped_ptr<SessionDescription> answer(
 
368
      f2_.CreateAnswer(offer.get(), opts, NULL));
 
369
  const ContentInfo* ac = answer->GetContentByName("audio");
 
370
  const ContentInfo* vc = answer->GetContentByName("data");
 
371
  ASSERT_TRUE(ac != NULL);
 
372
  ASSERT_TRUE(vc != NULL);
 
373
  EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type);
 
374
  EXPECT_EQ(std::string(NS_JINGLE_RTP), vc->type);
 
375
  const AudioContentDescription* acd =
 
376
      static_cast<const AudioContentDescription*>(ac->description);
 
377
  const DataContentDescription* vcd =
 
378
      static_cast<const DataContentDescription*>(vc->description);
 
379
  EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
 
380
  EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs());
 
381
  EXPECT_EQ(kAutoBandwidth, acd->bandwidth());  // negotiated auto bw
 
382
  EXPECT_NE(0U, acd->first_ssrc());             // a random nonzero ssrc
 
383
  EXPECT_TRUE(acd->rtcp_mux());                 // negotiated rtcp-mux
 
384
  ASSERT_CRYPTO(acd, false, 1U, CS_AES_CM_128_HMAC_SHA1_32);
 
385
  EXPECT_EQ(MEDIA_TYPE_DATA, vcd->type());
 
386
  EXPECT_EQ(MAKE_VECTOR(kDataCodecsAnswer), vcd->codecs());
 
387
  EXPECT_NE(0U, vcd->first_ssrc());             // a random nonzero ssrc
 
388
  EXPECT_TRUE(vcd->rtcp_mux());                 // negotiated rtcp-mux
 
389
  ASSERT_CRYPTO(vcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
 
390
}
 
391
 
 
392
// Create an audio, video, data answer without legacy StreamParams.
 
393
TEST_F(MediaSessionDescriptionFactoryTest,
 
394
       TestCreateAnswerWithoutLegacyStreams) {
 
395
  MediaSessionOptions opts;
 
396
  opts.has_video = true;
 
397
  opts.has_data = true;
 
398
  f1_.set_add_legacy_streams(false);
 
399
  f2_.set_add_legacy_streams(false);
 
400
  talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
 
401
  ASSERT_TRUE(offer.get() != NULL);
 
402
  talk_base::scoped_ptr<SessionDescription> answer(
 
403
      f2_.CreateAnswer(offer.get(), opts, NULL));
 
404
  const ContentInfo* ac = answer->GetContentByName("audio");
 
405
  const ContentInfo* vc = answer->GetContentByName("video");
 
406
  const ContentInfo* dc = answer->GetContentByName("data");
 
407
  ASSERT_TRUE(ac != NULL);
 
408
  ASSERT_TRUE(vc != NULL);
 
409
  const AudioContentDescription* acd =
 
410
      static_cast<const AudioContentDescription*>(ac->description);
 
411
  const VideoContentDescription* vcd =
 
412
      static_cast<const VideoContentDescription*>(vc->description);
 
413
  const DataContentDescription* dcd =
 
414
      static_cast<const DataContentDescription*>(dc->description);
 
415
 
 
416
  EXPECT_FALSE(acd->has_ssrcs());  // No StreamParams.
 
417
  EXPECT_FALSE(vcd->has_ssrcs());  // No StreamParams.
 
418
  EXPECT_FALSE(dcd->has_ssrcs());  // No StreamParams.
 
419
}
 
420
 
 
421
TEST_F(MediaSessionDescriptionFactoryTest, TestPartial) {
 
422
  MediaSessionOptions opts;
 
423
  opts.has_video = true;
 
424
  opts.has_data = true;
 
425
  f1_.set_secure(SEC_ENABLED);
 
426
  talk_base::scoped_ptr<SessionDescription>
 
427
      offer(f1_.CreateOffer(opts, NULL));
 
428
  ASSERT_TRUE(offer.get() != NULL);
 
429
  const ContentInfo* ac = offer->GetContentByName("audio");
 
430
  const ContentInfo* vc = offer->GetContentByName("video");
 
431
  const ContentInfo* dc = offer->GetContentByName("data");
 
432
  AudioContentDescription* acd = const_cast<AudioContentDescription*>(
 
433
      static_cast<const AudioContentDescription*>(ac->description));
 
434
  VideoContentDescription* vcd = const_cast<VideoContentDescription*>(
 
435
      static_cast<const VideoContentDescription*>(vc->description));
 
436
  DataContentDescription* dcd = const_cast<DataContentDescription*>(
 
437
      static_cast<const DataContentDescription*>(dc->description));
 
438
 
 
439
  EXPECT_FALSE(acd->partial());  // default is false.
 
440
  acd->set_partial(true);
 
441
  EXPECT_TRUE(acd->partial());
 
442
  acd->set_partial(false);
 
443
  EXPECT_FALSE(acd->partial());
 
444
 
 
445
  EXPECT_FALSE(vcd->partial());  // default is false.
 
446
  vcd->set_partial(true);
 
447
  EXPECT_TRUE(vcd->partial());
 
448
  vcd->set_partial(false);
 
449
  EXPECT_FALSE(vcd->partial());
 
450
 
 
451
  EXPECT_FALSE(dcd->partial());  // default is false.
 
452
  dcd->set_partial(true);
 
453
  EXPECT_TRUE(dcd->partial());
 
454
  dcd->set_partial(false);
 
455
  EXPECT_FALSE(dcd->partial());
 
456
}
 
457
 
 
458
// Create a typical video answer, and ensure it matches what we expect.
 
459
TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerRtcpMux) {
 
460
  MediaSessionOptions offer_opts;
 
461
  MediaSessionOptions answer_opts;
 
462
  answer_opts.has_video = true;
 
463
  offer_opts.has_video = true;
 
464
  answer_opts.has_data = true;
 
465
  offer_opts.has_data = true;
 
466
 
 
467
  talk_base::scoped_ptr<SessionDescription> offer(NULL);
 
468
  talk_base::scoped_ptr<SessionDescription> answer(NULL);
 
469
 
 
470
  offer_opts.rtcp_mux_enabled = true;
 
471
  answer_opts.rtcp_mux_enabled = true;
 
472
 
 
473
  offer.reset(f1_.CreateOffer(offer_opts, NULL));
 
474
  answer.reset(f2_.CreateAnswer(offer.get(), answer_opts, NULL));
 
475
  ASSERT_TRUE(NULL != GetFirstAudioContentDescription(offer.get()));
 
476
  ASSERT_TRUE(NULL != GetFirstVideoContentDescription(offer.get()));
 
477
  ASSERT_TRUE(NULL != GetFirstDataContentDescription(offer.get()));
 
478
  ASSERT_TRUE(NULL != GetFirstAudioContentDescription(answer.get()));
 
479
  ASSERT_TRUE(NULL != GetFirstVideoContentDescription(answer.get()));
 
480
  ASSERT_TRUE(NULL != GetFirstDataContentDescription(answer.get()));
 
481
  EXPECT_TRUE(GetFirstAudioContentDescription(offer.get())->rtcp_mux());
 
482
  EXPECT_TRUE(GetFirstVideoContentDescription(offer.get())->rtcp_mux());
 
483
  EXPECT_TRUE(GetFirstDataContentDescription(offer.get())->rtcp_mux());
 
484
  EXPECT_TRUE(GetFirstAudioContentDescription(answer.get())->rtcp_mux());
 
485
  EXPECT_TRUE(GetFirstVideoContentDescription(answer.get())->rtcp_mux());
 
486
  EXPECT_TRUE(GetFirstDataContentDescription(answer.get())->rtcp_mux());
 
487
 
 
488
  offer_opts.rtcp_mux_enabled = true;
 
489
  answer_opts.rtcp_mux_enabled = false;
 
490
 
 
491
  offer.reset(f1_.CreateOffer(offer_opts, NULL));
 
492
  answer.reset(f2_.CreateAnswer(offer.get(), answer_opts, NULL));
 
493
  ASSERT_TRUE(NULL != GetFirstAudioContentDescription(offer.get()));
 
494
  ASSERT_TRUE(NULL != GetFirstVideoContentDescription(offer.get()));
 
495
  ASSERT_TRUE(NULL != GetFirstDataContentDescription(offer.get()));
 
496
  ASSERT_TRUE(NULL != GetFirstAudioContentDescription(answer.get()));
 
497
  ASSERT_TRUE(NULL != GetFirstVideoContentDescription(answer.get()));
 
498
  ASSERT_TRUE(NULL != GetFirstDataContentDescription(answer.get()));
 
499
  EXPECT_TRUE(GetFirstAudioContentDescription(offer.get())->rtcp_mux());
 
500
  EXPECT_TRUE(GetFirstVideoContentDescription(offer.get())->rtcp_mux());
 
501
  EXPECT_TRUE(GetFirstDataContentDescription(offer.get())->rtcp_mux());
 
502
  EXPECT_FALSE(GetFirstAudioContentDescription(answer.get())->rtcp_mux());
 
503
  EXPECT_FALSE(GetFirstVideoContentDescription(answer.get())->rtcp_mux());
 
504
  EXPECT_FALSE(GetFirstDataContentDescription(answer.get())->rtcp_mux());
 
505
 
 
506
  offer_opts.rtcp_mux_enabled = false;
 
507
  answer_opts.rtcp_mux_enabled = true;
 
508
 
 
509
  offer.reset(f1_.CreateOffer(offer_opts, NULL));
 
510
  answer.reset(f2_.CreateAnswer(offer.get(), answer_opts, NULL));
 
511
  ASSERT_TRUE(NULL != GetFirstAudioContentDescription(offer.get()));
 
512
  ASSERT_TRUE(NULL != GetFirstVideoContentDescription(offer.get()));
 
513
  ASSERT_TRUE(NULL != GetFirstDataContentDescription(offer.get()));
 
514
  ASSERT_TRUE(NULL != GetFirstAudioContentDescription(answer.get()));
 
515
  ASSERT_TRUE(NULL != GetFirstVideoContentDescription(answer.get()));
 
516
  ASSERT_TRUE(NULL != GetFirstDataContentDescription(answer.get()));
 
517
  EXPECT_FALSE(GetFirstAudioContentDescription(offer.get())->rtcp_mux());
 
518
  EXPECT_FALSE(GetFirstVideoContentDescription(offer.get())->rtcp_mux());
 
519
  EXPECT_FALSE(GetFirstDataContentDescription(offer.get())->rtcp_mux());
 
520
  EXPECT_FALSE(GetFirstAudioContentDescription(answer.get())->rtcp_mux());
 
521
  EXPECT_FALSE(GetFirstVideoContentDescription(answer.get())->rtcp_mux());
 
522
  EXPECT_FALSE(GetFirstDataContentDescription(answer.get())->rtcp_mux());
 
523
 
 
524
  offer_opts.rtcp_mux_enabled = false;
 
525
  answer_opts.rtcp_mux_enabled = false;
 
526
 
 
527
  offer.reset(f1_.CreateOffer(offer_opts, NULL));
 
528
  answer.reset(f2_.CreateAnswer(offer.get(), answer_opts, NULL));
 
529
  ASSERT_TRUE(NULL != GetFirstAudioContentDescription(offer.get()));
 
530
  ASSERT_TRUE(NULL != GetFirstVideoContentDescription(offer.get()));
 
531
  ASSERT_TRUE(NULL != GetFirstDataContentDescription(offer.get()));
 
532
  ASSERT_TRUE(NULL != GetFirstAudioContentDescription(answer.get()));
 
533
  ASSERT_TRUE(NULL != GetFirstVideoContentDescription(answer.get()));
 
534
  ASSERT_TRUE(NULL != GetFirstDataContentDescription(answer.get()));
 
535
  EXPECT_FALSE(GetFirstAudioContentDescription(offer.get())->rtcp_mux());
 
536
  EXPECT_FALSE(GetFirstVideoContentDescription(offer.get())->rtcp_mux());
 
537
  EXPECT_FALSE(GetFirstDataContentDescription(offer.get())->rtcp_mux());
 
538
  EXPECT_FALSE(GetFirstAudioContentDescription(answer.get())->rtcp_mux());
 
539
  EXPECT_FALSE(GetFirstVideoContentDescription(answer.get())->rtcp_mux());
 
540
  EXPECT_FALSE(GetFirstDataContentDescription(answer.get())->rtcp_mux());
 
541
}
 
542
 
 
543
// Create an audio-only answer to a video offer.
 
544
TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswerToVideo) {
 
545
  MediaSessionOptions opts;
 
546
  opts.has_video = true;
 
547
  talk_base::scoped_ptr<SessionDescription>
 
548
      offer(f1_.CreateOffer(opts, NULL));
 
549
  ASSERT_TRUE(offer.get() != NULL);
 
550
  talk_base::scoped_ptr<SessionDescription> answer(
 
551
      f2_.CreateAnswer(offer.get(), MediaSessionOptions(), NULL));
 
552
  const ContentInfo* ac = answer->GetContentByName("audio");
 
553
  const ContentInfo* vc = answer->GetContentByName("video");
 
554
  ASSERT_TRUE(ac != NULL);
 
555
  ASSERT_TRUE(vc == NULL);
 
556
}
 
557
 
 
558
// Create an audio-only answer to a video offer.
 
559
TEST_F(MediaSessionDescriptionFactoryTest, TestCreateNoDataAnswerToDataOffer) {
 
560
  MediaSessionOptions opts;
 
561
  opts.has_data = true;
 
562
  talk_base::scoped_ptr<SessionDescription>
 
563
      offer(f1_.CreateOffer(opts, NULL));
 
564
  ASSERT_TRUE(offer.get() != NULL);
 
565
  talk_base::scoped_ptr<SessionDescription> answer(
 
566
      f2_.CreateAnswer(offer.get(), MediaSessionOptions(), NULL));
 
567
  const ContentInfo* ac = answer->GetContentByName("audio");
 
568
  const ContentInfo* dc = answer->GetContentByName("data");
 
569
  ASSERT_TRUE(ac != NULL);
 
570
  ASSERT_TRUE(dc == NULL);
 
571
}
 
572
 
 
573
// Create an audio and video offer with:
 
574
// - one video track
 
575
// - two audio tracks
 
576
// - two data tracks
 
577
// and ensure it matches what we expect. Also updates the initial offer by
 
578
// adding a new video track and replaces one of the audio tracks.
 
579
TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoOffer) {
 
580
  MediaSessionOptions opts;
 
581
  opts.AddStream(MEDIA_TYPE_VIDEO, kVideoTrack1, kMediaStream1);
 
582
  opts.AddStream(MEDIA_TYPE_AUDIO, kAudioTrack1, kMediaStream1);
 
583
  opts.AddStream(MEDIA_TYPE_AUDIO, kAudioTrack2, kMediaStream1);
 
584
  opts.AddStream(MEDIA_TYPE_DATA, kDataTrack1, kMediaStream1);
 
585
  opts.AddStream(MEDIA_TYPE_DATA, kDataTrack2, kMediaStream1);
 
586
 
 
587
  f1_.set_secure(SEC_ENABLED);
 
588
  talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
 
589
 
 
590
  ASSERT_TRUE(offer.get() != NULL);
 
591
  const ContentInfo* ac = offer->GetContentByName("audio");
 
592
  const ContentInfo* vc = offer->GetContentByName("video");
 
593
  const ContentInfo* dc = offer->GetContentByName("data");
 
594
  ASSERT_TRUE(ac != NULL);
 
595
  ASSERT_TRUE(vc != NULL);
 
596
  ASSERT_TRUE(dc != NULL);
 
597
  const AudioContentDescription* acd =
 
598
      static_cast<const AudioContentDescription*>(ac->description);
 
599
  const VideoContentDescription* vcd =
 
600
      static_cast<const VideoContentDescription*>(vc->description);
 
601
  const DataContentDescription* dcd =
 
602
      static_cast<const DataContentDescription*>(dc->description);
 
603
  EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
 
604
  EXPECT_EQ(f1_.audio_codecs(), acd->codecs());
 
605
 
 
606
  const StreamParamsVec& audio_streams = acd->streams();
 
607
  ASSERT_EQ(2U, audio_streams.size());
 
608
  EXPECT_EQ(audio_streams[0].cname , audio_streams[1].cname);
 
609
  EXPECT_EQ(kAudioTrack1, audio_streams[0].name);
 
610
  ASSERT_EQ(1U, audio_streams[0].ssrcs.size());
 
611
  EXPECT_NE(0U, audio_streams[0].ssrcs[0]);
 
612
  EXPECT_EQ(kAudioTrack2, audio_streams[1].name);
 
613
  ASSERT_EQ(1U, audio_streams[1].ssrcs.size());
 
614
  EXPECT_NE(0U, audio_streams[1].ssrcs[0]);
 
615
 
 
616
  EXPECT_EQ(kAutoBandwidth, acd->bandwidth());  // default bandwidth (auto)
 
617
  EXPECT_TRUE(acd->rtcp_mux());                 // rtcp-mux defaults on
 
618
  ASSERT_CRYPTO(acd, false, 2U, CS_AES_CM_128_HMAC_SHA1_32);
 
619
 
 
620
  EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type());
 
621
  EXPECT_EQ(f1_.video_codecs(), vcd->codecs());
 
622
  ASSERT_CRYPTO(vcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
 
623
 
 
624
  const StreamParamsVec& video_streams = vcd->streams();
 
625
  ASSERT_EQ(1U, video_streams.size());
 
626
  EXPECT_EQ(video_streams[0].cname, audio_streams[0].cname);
 
627
  EXPECT_EQ(kVideoTrack1, video_streams[0].name);
 
628
  EXPECT_EQ(kAutoBandwidth, vcd->bandwidth());  // default bandwidth (auto)
 
629
  EXPECT_TRUE(vcd->rtcp_mux());                 // rtcp-mux defaults on
 
630
 
 
631
  EXPECT_EQ(MEDIA_TYPE_DATA, dcd->type());
 
632
  EXPECT_EQ(f1_.data_codecs(), dcd->codecs());
 
633
  ASSERT_CRYPTO(dcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
 
634
 
 
635
  const StreamParamsVec& data_streams = dcd->streams();
 
636
  ASSERT_EQ(2U, data_streams.size());
 
637
  EXPECT_EQ(data_streams[0].cname , data_streams[1].cname);
 
638
  EXPECT_EQ(kDataTrack1, data_streams[0].name);
 
639
  ASSERT_EQ(1U, data_streams[0].ssrcs.size());
 
640
  EXPECT_NE(0U, data_streams[0].ssrcs[0]);
 
641
  EXPECT_EQ(kDataTrack2, data_streams[1].name);
 
642
  ASSERT_EQ(1U, data_streams[1].ssrcs.size());
 
643
  EXPECT_NE(0U, data_streams[1].ssrcs[0]);
 
644
 
 
645
  EXPECT_EQ(cricket::kDataMaxBandwidth,
 
646
            dcd->bandwidth());                  // default bandwidth (auto)
 
647
  EXPECT_TRUE(dcd->rtcp_mux());                 // rtcp-mux defaults on
 
648
  ASSERT_CRYPTO(dcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
 
649
 
 
650
 
 
651
  // Update the offer. Add a new video track that is not synched to the
 
652
  // other tracks and replace audio track 2 with audio track 3.
 
653
  opts.AddStream(MEDIA_TYPE_VIDEO, kVideoTrack2, kMediaStream2);
 
654
  opts.RemoveStream(MEDIA_TYPE_AUDIO, kAudioTrack2);
 
655
  opts.AddStream(MEDIA_TYPE_AUDIO, kAudioTrack3, kMediaStream1);
 
656
  opts.RemoveStream(MEDIA_TYPE_DATA, kDataTrack2);
 
657
  opts.AddStream(MEDIA_TYPE_DATA, kDataTrack3, kMediaStream1);
 
658
  talk_base::scoped_ptr<SessionDescription>
 
659
      updated_offer(f1_.CreateOffer(opts, offer.get()));
 
660
 
 
661
  ASSERT_TRUE(updated_offer.get() != NULL);
 
662
  ac = updated_offer->GetContentByName("audio");
 
663
  vc = updated_offer->GetContentByName("video");
 
664
  dc = updated_offer->GetContentByName("data");
 
665
  ASSERT_TRUE(ac != NULL);
 
666
  ASSERT_TRUE(vc != NULL);
 
667
  ASSERT_TRUE(dc != NULL);
 
668
  const AudioContentDescription* updated_acd =
 
669
      static_cast<const AudioContentDescription*>(ac->description);
 
670
  const VideoContentDescription* updated_vcd =
 
671
      static_cast<const VideoContentDescription*>(vc->description);
 
672
  const DataContentDescription* updated_dcd =
 
673
      static_cast<const DataContentDescription*>(dc->description);
 
674
 
 
675
  EXPECT_EQ(acd->type(), updated_acd->type());
 
676
  EXPECT_EQ(acd->codecs(), updated_acd->codecs());
 
677
  EXPECT_EQ(vcd->type(), updated_vcd->type());
 
678
  EXPECT_EQ(vcd->codecs(), updated_vcd->codecs());
 
679
  EXPECT_EQ(dcd->type(), updated_dcd->type());
 
680
  EXPECT_EQ(dcd->codecs(), updated_dcd->codecs());
 
681
  ASSERT_CRYPTO(updated_acd, false, 2U, CS_AES_CM_128_HMAC_SHA1_32);
 
682
  EXPECT_TRUE(CompareCryptoParams(acd->cryptos(), updated_acd->cryptos()));
 
683
  ASSERT_CRYPTO(updated_vcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
 
684
  EXPECT_TRUE(CompareCryptoParams(vcd->cryptos(), updated_vcd->cryptos()));
 
685
  ASSERT_CRYPTO(updated_dcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
 
686
  EXPECT_TRUE(CompareCryptoParams(dcd->cryptos(), updated_dcd->cryptos()));
 
687
 
 
688
  const StreamParamsVec& updated_audio_streams = updated_acd->streams();
 
689
  ASSERT_EQ(2U, updated_audio_streams.size());
 
690
  EXPECT_EQ(audio_streams[0], updated_audio_streams[0]);
 
691
  EXPECT_EQ(kAudioTrack3, updated_audio_streams[1].name);  // New audio track.
 
692
  ASSERT_EQ(1U, updated_audio_streams[1].ssrcs.size());
 
693
  EXPECT_NE(0U, updated_audio_streams[1].ssrcs[0]);
 
694
  EXPECT_EQ(updated_audio_streams[0].cname, updated_audio_streams[1].cname);
 
695
 
 
696
  const StreamParamsVec& updated_video_streams = updated_vcd->streams();
 
697
  ASSERT_EQ(2U, updated_video_streams.size());
 
698
  EXPECT_EQ(video_streams[0], updated_video_streams[0]);
 
699
  EXPECT_EQ(kVideoTrack2, updated_video_streams[1].name);
 
700
  EXPECT_NE(updated_video_streams[1].cname, updated_video_streams[0].cname);
 
701
 
 
702
  const StreamParamsVec& updated_data_streams = updated_dcd->streams();
 
703
  ASSERT_EQ(2U, updated_data_streams.size());
 
704
  EXPECT_EQ(data_streams[0], updated_data_streams[0]);
 
705
  EXPECT_EQ(kDataTrack3, updated_data_streams[1].name);  // New data track.
 
706
  ASSERT_EQ(1U, updated_data_streams[1].ssrcs.size());
 
707
  EXPECT_NE(0U, updated_data_streams[1].ssrcs[0]);
 
708
  EXPECT_EQ(updated_data_streams[0].cname, updated_data_streams[1].cname);
 
709
}
 
710
 
 
711
// Create an audio and video answer to a standard video offer with:
 
712
// - one video track
 
713
// - two audio tracks
 
714
// - two data tracks
 
715
// and ensure it matches what we expect. Also updates the initial answer by
 
716
// adding a new video track and removes one of the audio tracks.
 
717
TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoAnswer) {
 
718
  MediaSessionOptions offer_opts;
 
719
  offer_opts.has_video = true;
 
720
  offer_opts.has_data = true;
 
721
  f1_.set_secure(SEC_ENABLED);
 
722
  f2_.set_secure(SEC_ENABLED);
 
723
  talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(offer_opts,
 
724
                                                                  NULL));
 
725
 
 
726
  MediaSessionOptions opts;
 
727
  opts.AddStream(MEDIA_TYPE_VIDEO, kVideoTrack1, kMediaStream1);
 
728
  opts.AddStream(MEDIA_TYPE_AUDIO, kAudioTrack1, kMediaStream1);
 
729
  opts.AddStream(MEDIA_TYPE_AUDIO, kAudioTrack2, kMediaStream1);
 
730
  opts.AddStream(MEDIA_TYPE_DATA, kDataTrack1, kMediaStream1);
 
731
  opts.AddStream(MEDIA_TYPE_DATA, kDataTrack2, kMediaStream1);
 
732
 
 
733
  talk_base::scoped_ptr<SessionDescription>
 
734
      answer(f2_.CreateAnswer(offer.get(), opts, NULL));
 
735
 
 
736
  ASSERT_TRUE(answer.get() != NULL);
 
737
  const ContentInfo* ac = answer->GetContentByName("audio");
 
738
  const ContentInfo* vc = answer->GetContentByName("video");
 
739
  const ContentInfo* dc = answer->GetContentByName("data");
 
740
  ASSERT_TRUE(ac != NULL);
 
741
  ASSERT_TRUE(vc != NULL);
 
742
  ASSERT_TRUE(dc != NULL);
 
743
  const AudioContentDescription* acd =
 
744
      static_cast<const AudioContentDescription*>(ac->description);
 
745
  const VideoContentDescription* vcd =
 
746
      static_cast<const VideoContentDescription*>(vc->description);
 
747
  const DataContentDescription* dcd =
 
748
      static_cast<const DataContentDescription*>(dc->description);
 
749
  ASSERT_CRYPTO(acd, false, 1U, CS_AES_CM_128_HMAC_SHA1_32);
 
750
  ASSERT_CRYPTO(vcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
 
751
  ASSERT_CRYPTO(dcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
 
752
 
 
753
  EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
 
754
  EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs());
 
755
 
 
756
  const StreamParamsVec& audio_streams = acd->streams();
 
757
  ASSERT_EQ(2U, audio_streams.size());
 
758
  EXPECT_TRUE(audio_streams[0].cname ==  audio_streams[1].cname);
 
759
  EXPECT_EQ(kAudioTrack1, audio_streams[0].name);
 
760
  ASSERT_EQ(1U, audio_streams[0].ssrcs.size());
 
761
  EXPECT_NE(0U, audio_streams[0].ssrcs[0]);
 
762
  EXPECT_EQ(kAudioTrack2, audio_streams[1].name);
 
763
  ASSERT_EQ(1U, audio_streams[1].ssrcs.size());
 
764
  EXPECT_NE(0U, audio_streams[1].ssrcs[0]);
 
765
 
 
766
  EXPECT_EQ(kAutoBandwidth, acd->bandwidth());  // default bandwidth (auto)
 
767
  EXPECT_TRUE(acd->rtcp_mux());                 // rtcp-mux defaults on
 
768
 
 
769
  EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type());
 
770
  EXPECT_EQ(MAKE_VECTOR(kVideoCodecsAnswer), vcd->codecs());
 
771
 
 
772
  const StreamParamsVec& video_streams = vcd->streams();
 
773
  ASSERT_EQ(1U, video_streams.size());
 
774
  EXPECT_EQ(video_streams[0].cname, audio_streams[0].cname);
 
775
  EXPECT_EQ(kVideoTrack1, video_streams[0].name);
 
776
  EXPECT_EQ(kAutoBandwidth, vcd->bandwidth());  // default bandwidth (auto)
 
777
  EXPECT_TRUE(vcd->rtcp_mux());                 // rtcp-mux defaults on
 
778
 
 
779
  EXPECT_EQ(MEDIA_TYPE_DATA, dcd->type());
 
780
  EXPECT_EQ(MAKE_VECTOR(kDataCodecsAnswer), dcd->codecs());
 
781
 
 
782
  const StreamParamsVec& data_streams = dcd->streams();
 
783
  ASSERT_EQ(2U, data_streams.size());
 
784
  EXPECT_TRUE(data_streams[0].cname ==  data_streams[1].cname);
 
785
  EXPECT_EQ(kDataTrack1, data_streams[0].name);
 
786
  ASSERT_EQ(1U, data_streams[0].ssrcs.size());
 
787
  EXPECT_NE(0U, data_streams[0].ssrcs[0]);
 
788
  EXPECT_EQ(kDataTrack2, data_streams[1].name);
 
789
  ASSERT_EQ(1U, data_streams[1].ssrcs.size());
 
790
  EXPECT_NE(0U, data_streams[1].ssrcs[0]);
 
791
 
 
792
  EXPECT_EQ(cricket::kDataMaxBandwidth,
 
793
            dcd->bandwidth());                  // default bandwidth (auto)
 
794
  EXPECT_TRUE(dcd->rtcp_mux());                 // rtcp-mux defaults on
 
795
 
 
796
  // Update the answer. Add a new video track that is not synched to the
 
797
  // other traacks and remove 1 audio track.
 
798
  opts.AddStream(MEDIA_TYPE_VIDEO, kVideoTrack2, kMediaStream2);
 
799
  opts.RemoveStream(MEDIA_TYPE_AUDIO, kAudioTrack2);
 
800
  opts.RemoveStream(MEDIA_TYPE_DATA, kDataTrack2);
 
801
  talk_base::scoped_ptr<SessionDescription>
 
802
      updated_answer(f2_.CreateAnswer(offer.get(), opts, answer.get()));
 
803
 
 
804
  ASSERT_TRUE(updated_answer.get() != NULL);
 
805
  ac = updated_answer->GetContentByName("audio");
 
806
  vc = updated_answer->GetContentByName("video");
 
807
  dc = updated_answer->GetContentByName("data");
 
808
  ASSERT_TRUE(ac != NULL);
 
809
  ASSERT_TRUE(vc != NULL);
 
810
  ASSERT_TRUE(dc != NULL);
 
811
  const AudioContentDescription* updated_acd =
 
812
      static_cast<const AudioContentDescription*>(ac->description);
 
813
  const VideoContentDescription* updated_vcd =
 
814
      static_cast<const VideoContentDescription*>(vc->description);
 
815
  const DataContentDescription* updated_dcd =
 
816
      static_cast<const DataContentDescription*>(dc->description);
 
817
 
 
818
  ASSERT_CRYPTO(updated_acd, false, 1U, CS_AES_CM_128_HMAC_SHA1_32);
 
819
  EXPECT_TRUE(CompareCryptoParams(acd->cryptos(), updated_acd->cryptos()));
 
820
  ASSERT_CRYPTO(updated_vcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
 
821
  EXPECT_TRUE(CompareCryptoParams(vcd->cryptos(), updated_vcd->cryptos()));
 
822
  ASSERT_CRYPTO(updated_dcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
 
823
  EXPECT_TRUE(CompareCryptoParams(dcd->cryptos(), updated_dcd->cryptos()));
 
824
 
 
825
  EXPECT_EQ(acd->type(), updated_acd->type());
 
826
  EXPECT_EQ(acd->codecs(), updated_acd->codecs());
 
827
  EXPECT_EQ(vcd->type(), updated_vcd->type());
 
828
  EXPECT_EQ(vcd->codecs(), updated_vcd->codecs());
 
829
  EXPECT_EQ(dcd->type(), updated_dcd->type());
 
830
  EXPECT_EQ(dcd->codecs(), updated_dcd->codecs());
 
831
 
 
832
  const StreamParamsVec& updated_audio_streams = updated_acd->streams();
 
833
  ASSERT_EQ(1U, updated_audio_streams.size());
 
834
  EXPECT_TRUE(audio_streams[0] ==  updated_audio_streams[0]);
 
835
 
 
836
  const StreamParamsVec& updated_video_streams = updated_vcd->streams();
 
837
  ASSERT_EQ(2U, updated_video_streams.size());
 
838
  EXPECT_EQ(video_streams[0], updated_video_streams[0]);
 
839
  EXPECT_EQ(kVideoTrack2, updated_video_streams[1].name);
 
840
  EXPECT_NE(updated_video_streams[1].cname, updated_video_streams[0].cname);
 
841
 
 
842
  const StreamParamsVec& updated_data_streams = updated_dcd->streams();
 
843
  ASSERT_EQ(1U, updated_data_streams.size());
 
844
  EXPECT_TRUE(data_streams[0] == updated_data_streams[0]);
 
845
}
 
846
 
 
847
TEST(MediaSessionDescription, CopySessionDescription) {
 
848
  SessionDescription source;
 
849
  cricket::ContentGroup group(cricket::CN_AUDIO);
 
850
  source.AddGroup(group);
 
851
  AudioContentDescription* acd(new AudioContentDescription());
 
852
  acd->set_codecs(MAKE_VECTOR(kAudioCodecs1));
 
853
  acd->AddLegacyStream(1);
 
854
  source.AddContent(cricket::CN_AUDIO, cricket::NS_JINGLE_RTP, acd);
 
855
  VideoContentDescription* vcd(new VideoContentDescription());
 
856
  vcd->set_codecs(MAKE_VECTOR(kVideoCodecs1));
 
857
  vcd->AddLegacyStream(2);
 
858
  source.AddContent(cricket::CN_VIDEO, cricket::NS_JINGLE_RTP, vcd);
 
859
 
 
860
  talk_base::scoped_ptr<SessionDescription> copy(source.Copy());
 
861
  ASSERT_TRUE(copy.get() != NULL);
 
862
  EXPECT_TRUE(copy->HasGroup(cricket::CN_AUDIO));
 
863
  const ContentInfo* ac = copy->GetContentByName("audio");
 
864
  const ContentInfo* vc = copy->GetContentByName("video");
 
865
  ASSERT_TRUE(ac != NULL);
 
866
  ASSERT_TRUE(vc != NULL);
 
867
  EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type);
 
868
  const AudioContentDescription* acd_copy =
 
869
      static_cast<const AudioContentDescription*>(ac->description);
 
870
  EXPECT_EQ(acd->codecs(), acd_copy->codecs());
 
871
  EXPECT_EQ(1u, acd->first_ssrc());
 
872
 
 
873
  EXPECT_EQ(std::string(NS_JINGLE_RTP), vc->type);
 
874
  const VideoContentDescription* vcd_copy =
 
875
      static_cast<const VideoContentDescription*>(vc->description);
 
876
  EXPECT_EQ(vcd->codecs(), vcd_copy->codecs());
 
877
  EXPECT_EQ(2u, vcd->first_ssrc());
 
878
}