3
* Copyright 2004--2011, Google Inc.
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
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.
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.
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"
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)
44
#define ASSERT_CRYPTO(c, r, s, cs) \
45
ASSERT_EQ(false, cd->crypto_required()); \
46
ASSERT_EQ(0U, cd->cryptos().size());
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;
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),
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),
90
static const AudioCodec kAudioCodecsAnswer[] = {
91
AudioCodec(102, "iLBC", 8000, 13300, 1, 2),
92
AudioCodec(0, "PCMU", 8000, 64000, 1, 1),
95
static const VideoCodec kVideoCodecs1[] = {
96
VideoCodec(96, "H264-SVC", 320, 200, 30, 2),
97
VideoCodec(97, "H264", 320, 200, 30, 1)
100
static const VideoCodec kVideoCodecs2[] = {
101
VideoCodec(126, "H264", 320, 200, 30, 2),
102
VideoCodec(127, "H263", 320, 200, 30, 1)
105
static const VideoCodec kVideoCodecsAnswer[] = {
106
VideoCodec(97, "H264", 320, 200, 30, 2)
109
static const DataCodec kDataCodecs1[] = {
110
DataCodec(96, "binary-data", 2),
111
DataCodec(97, "utf8-text", 1)
114
static const DataCodec kDataCodecs2[] = {
115
DataCodec(126, "binary-data", 2),
116
DataCodec(127, "utf8-text", 1)
119
static const DataCodec kDataCodecsAnswer[] = {
120
DataCodec(96, "binary-data", 2),
121
DataCodec(97, "utf8-text", 1)
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};
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";
141
class MediaSessionDescriptionFactoryTest : public testing::Test {
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));
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));
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);
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;
173
StreamParamsVec video_streams;
174
video_streams.push_back(simulcast_params);
176
return video_streams;
178
bool CompareCryptoParams(const CryptoParamsVec& c1,
179
const CryptoParamsVec& c2) {
180
if (c1.size() != c2.size())
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)
191
MediaSessionDescriptionFactory f1_;
192
MediaSessionDescriptionFactory f2_;
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);
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);
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);
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);
299
EXPECT_FALSE(vcd->has_ssrcs()); // No StreamParams.
300
EXPECT_FALSE(acd->has_ssrcs()); // No StreamParams.
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);
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);
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);
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);
416
EXPECT_FALSE(acd->has_ssrcs()); // No StreamParams.
417
EXPECT_FALSE(vcd->has_ssrcs()); // No StreamParams.
418
EXPECT_FALSE(dcd->has_ssrcs()); // No StreamParams.
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));
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());
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());
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());
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;
467
talk_base::scoped_ptr<SessionDescription> offer(NULL);
468
talk_base::scoped_ptr<SessionDescription> answer(NULL);
470
offer_opts.rtcp_mux_enabled = true;
471
answer_opts.rtcp_mux_enabled = true;
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());
488
offer_opts.rtcp_mux_enabled = true;
489
answer_opts.rtcp_mux_enabled = false;
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());
506
offer_opts.rtcp_mux_enabled = false;
507
answer_opts.rtcp_mux_enabled = true;
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());
524
offer_opts.rtcp_mux_enabled = false;
525
answer_opts.rtcp_mux_enabled = false;
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());
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);
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);
573
// Create an audio and video offer with:
575
// - two audio 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);
587
f1_.set_secure(SEC_ENABLED);
588
talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
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());
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]);
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);
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);
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
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);
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]);
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);
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()));
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);
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()));
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);
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);
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);
711
// Create an audio and video answer to a standard video offer with:
713
// - two audio 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,
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);
733
talk_base::scoped_ptr<SessionDescription>
734
answer(f2_.CreateAnswer(offer.get(), opts, NULL));
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);
753
EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
754
EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs());
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]);
766
EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto)
767
EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on
769
EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type());
770
EXPECT_EQ(MAKE_VECTOR(kVideoCodecsAnswer), vcd->codecs());
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
779
EXPECT_EQ(MEDIA_TYPE_DATA, dcd->type());
780
EXPECT_EQ(MAKE_VECTOR(kDataCodecsAnswer), dcd->codecs());
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]);
792
EXPECT_EQ(cricket::kDataMaxBandwidth,
793
dcd->bandwidth()); // default bandwidth (auto)
794
EXPECT_TRUE(dcd->rtcp_mux()); // rtcp-mux defaults on
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()));
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);
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()));
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());
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]);
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);
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]);
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);
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());
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());