OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2004 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 i != cryptos.end(); ++i) { | 204 i != cryptos.end(); ++i) { |
205 if (rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || | 205 if (rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || |
206 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio && | 206 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio && |
207 !bundle)) { | 207 !bundle)) { |
208 return CreateCryptoParams(i->tag, i->cipher_suite, crypto); | 208 return CreateCryptoParams(i->tag, i->cipher_suite, crypto); |
209 } | 209 } |
210 } | 210 } |
211 return false; | 211 return false; |
212 } | 212 } |
213 | 213 |
214 static const StreamParams* FindFirstStreamParamsByCname( | |
215 const StreamParamsVec& params_vec, | |
216 const std::string& cname) { | |
217 for (StreamParamsVec::const_iterator it = params_vec.begin(); | |
218 it != params_vec.end(); ++it) { | |
219 if (cname == it->cname) | |
220 return &*it; | |
221 } | |
222 return NULL; | |
223 } | |
224 | |
225 // Generates a new CNAME or the CNAME of an already existing StreamParams | |
226 // if a StreamParams exist for another Stream in streams with sync_label | |
227 // sync_label. | |
228 static bool GenerateCname(const StreamParamsVec& params_vec, | |
229 const MediaSessionOptions::Streams& streams, | |
230 const std::string& synch_label, | |
231 std::string* cname) { | |
232 ASSERT(cname != NULL); | |
233 if (!cname) | |
234 return false; | |
235 | |
236 // Check if a CNAME exist for any of the other synched streams. | |
237 for (MediaSessionOptions::Streams::const_iterator stream_it = streams.begin(); | |
238 stream_it != streams.end() ; ++stream_it) { | |
239 if (synch_label != stream_it->sync_label) | |
240 continue; | |
241 | |
242 // groupid is empty for StreamParams generated using | |
243 // MediaSessionDescriptionFactory. | |
244 const StreamParams* param = GetStreamByIds(params_vec, "", stream_it->id); | |
245 if (param) { | |
246 *cname = param->cname; | |
247 return true; | |
248 } | |
249 } | |
250 // No other stream seems to exist that we should sync with. | |
251 // Generate a random string for the RTCP CNAME, as stated in RFC 6222. | |
252 // This string is only used for synchronization, and therefore is opaque. | |
253 do { | |
254 if (!rtc::CreateRandomString(16, cname)) { | |
255 ASSERT(false); | |
256 return false; | |
257 } | |
258 } while (FindFirstStreamParamsByCname(params_vec, *cname)); | |
259 | |
260 return true; | |
261 } | |
262 | |
263 // Generate random SSRC values that are not already present in |params_vec|. | 214 // Generate random SSRC values that are not already present in |params_vec|. |
264 // The generated values are added to |ssrcs|. | 215 // The generated values are added to |ssrcs|. |
265 // |num_ssrcs| is the number of the SSRC will be generated. | 216 // |num_ssrcs| is the number of the SSRC will be generated. |
266 static void GenerateSsrcs(const StreamParamsVec& params_vec, | 217 static void GenerateSsrcs(const StreamParamsVec& params_vec, |
267 int num_ssrcs, | 218 int num_ssrcs, |
268 std::vector<uint32_t>* ssrcs) { | 219 std::vector<uint32_t>* ssrcs) { |
269 for (int i = 0; i < num_ssrcs; i++) { | 220 for (int i = 0; i < num_ssrcs; i++) { |
270 uint32_t candidate; | 221 uint32_t candidate; |
271 do { | 222 do { |
272 candidate = rtc::CreateRandomNonZeroId(); | 223 candidate = rtc::CreateRandomNonZeroId(); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 | 388 |
438 static bool IsSctp(const MediaContentDescription* desc) { | 389 static bool IsSctp(const MediaContentDescription* desc) { |
439 return ((desc->protocol() == kMediaProtocolSctp) || | 390 return ((desc->protocol() == kMediaProtocolSctp) || |
440 (desc->protocol() == kMediaProtocolDtlsSctp)); | 391 (desc->protocol() == kMediaProtocolDtlsSctp)); |
441 } | 392 } |
442 | 393 |
443 // Adds a StreamParams for each Stream in Streams with media type | 394 // Adds a StreamParams for each Stream in Streams with media type |
444 // media_type to content_description. | 395 // media_type to content_description. |
445 // |current_params| - All currently known StreamParams of any media type. | 396 // |current_params| - All currently known StreamParams of any media type. |
446 template <class C> | 397 template <class C> |
447 static bool AddStreamParams( | 398 static bool AddStreamParams(MediaType media_type, |
448 MediaType media_type, | 399 const MediaSessionOptions& options, |
449 const MediaSessionOptions::Streams& streams, | 400 StreamParamsVec* current_streams, |
450 StreamParamsVec* current_streams, | 401 MediaContentDescriptionImpl<C>* content_description, |
451 MediaContentDescriptionImpl<C>* content_description, | 402 const bool add_legacy_stream) { |
452 const bool add_legacy_stream) { | |
453 const bool include_rtx_streams = | 403 const bool include_rtx_streams = |
454 ContainsRtxCodec(content_description->codecs()); | 404 ContainsRtxCodec(content_description->codecs()); |
455 | 405 |
| 406 const MediaSessionOptions::Streams& streams = options.streams; |
456 if (streams.empty() && add_legacy_stream) { | 407 if (streams.empty() && add_legacy_stream) { |
457 // TODO(perkj): Remove this legacy stream when all apps use StreamParams. | 408 // TODO(perkj): Remove this legacy stream when all apps use StreamParams. |
458 std::vector<uint32_t> ssrcs; | 409 std::vector<uint32_t> ssrcs; |
459 if (IsSctp(content_description)) { | 410 if (IsSctp(content_description)) { |
460 GenerateSctpSids(*current_streams, &ssrcs); | 411 GenerateSctpSids(*current_streams, &ssrcs); |
461 } else { | 412 } else { |
462 int num_ssrcs = include_rtx_streams ? 2 : 1; | 413 int num_ssrcs = include_rtx_streams ? 2 : 1; |
463 GenerateSsrcs(*current_streams, num_ssrcs, &ssrcs); | 414 GenerateSsrcs(*current_streams, num_ssrcs, &ssrcs); |
464 } | 415 } |
465 if (include_rtx_streams) { | 416 if (include_rtx_streams) { |
(...skipping 10 matching lines...) Expand all Loading... |
476 stream_it != streams.end(); ++stream_it) { | 427 stream_it != streams.end(); ++stream_it) { |
477 if (stream_it->type != media_type) | 428 if (stream_it->type != media_type) |
478 continue; // Wrong media type. | 429 continue; // Wrong media type. |
479 | 430 |
480 const StreamParams* param = | 431 const StreamParams* param = |
481 GetStreamByIds(*current_streams, "", stream_it->id); | 432 GetStreamByIds(*current_streams, "", stream_it->id); |
482 // groupid is empty for StreamParams generated using | 433 // groupid is empty for StreamParams generated using |
483 // MediaSessionDescriptionFactory. | 434 // MediaSessionDescriptionFactory. |
484 if (!param) { | 435 if (!param) { |
485 // This is a new stream. | 436 // This is a new stream. |
486 // Get a CNAME. Either new or same as one of the other synched streams. | |
487 std::string cname; | |
488 if (!GenerateCname(*current_streams, streams, stream_it->sync_label, | |
489 &cname)) { | |
490 return false; | |
491 } | |
492 | |
493 std::vector<uint32_t> ssrcs; | 437 std::vector<uint32_t> ssrcs; |
494 if (IsSctp(content_description)) { | 438 if (IsSctp(content_description)) { |
495 GenerateSctpSids(*current_streams, &ssrcs); | 439 GenerateSctpSids(*current_streams, &ssrcs); |
496 } else { | 440 } else { |
497 GenerateSsrcs(*current_streams, stream_it->num_sim_layers, &ssrcs); | 441 GenerateSsrcs(*current_streams, stream_it->num_sim_layers, &ssrcs); |
498 } | 442 } |
499 StreamParams stream_param; | 443 StreamParams stream_param; |
500 stream_param.id = stream_it->id; | 444 stream_param.id = stream_it->id; |
501 // Add the generated ssrc. | 445 // Add the generated ssrc. |
502 for (size_t i = 0; i < ssrcs.size(); ++i) { | 446 for (size_t i = 0; i < ssrcs.size(); ++i) { |
503 stream_param.ssrcs.push_back(ssrcs[i]); | 447 stream_param.ssrcs.push_back(ssrcs[i]); |
504 } | 448 } |
505 if (stream_it->num_sim_layers > 1) { | 449 if (stream_it->num_sim_layers > 1) { |
506 SsrcGroup group(kSimSsrcGroupSemantics, stream_param.ssrcs); | 450 SsrcGroup group(kSimSsrcGroupSemantics, stream_param.ssrcs); |
507 stream_param.ssrc_groups.push_back(group); | 451 stream_param.ssrc_groups.push_back(group); |
508 } | 452 } |
509 // Generate extra ssrcs for include_rtx_streams case. | 453 // Generate extra ssrcs for include_rtx_streams case. |
510 if (include_rtx_streams) { | 454 if (include_rtx_streams) { |
511 // Generate an RTX ssrc for every ssrc in the group. | 455 // Generate an RTX ssrc for every ssrc in the group. |
512 std::vector<uint32_t> rtx_ssrcs; | 456 std::vector<uint32_t> rtx_ssrcs; |
513 GenerateSsrcs(*current_streams, static_cast<int>(ssrcs.size()), | 457 GenerateSsrcs(*current_streams, static_cast<int>(ssrcs.size()), |
514 &rtx_ssrcs); | 458 &rtx_ssrcs); |
515 for (size_t i = 0; i < ssrcs.size(); ++i) { | 459 for (size_t i = 0; i < ssrcs.size(); ++i) { |
516 stream_param.AddFidSsrc(ssrcs[i], rtx_ssrcs[i]); | 460 stream_param.AddFidSsrc(ssrcs[i], rtx_ssrcs[i]); |
517 } | 461 } |
518 content_description->set_multistream(true); | 462 content_description->set_multistream(true); |
519 } | 463 } |
520 stream_param.cname = cname; | 464 stream_param.cname = options.rtcp_cname; |
521 stream_param.sync_label = stream_it->sync_label; | 465 stream_param.sync_label = stream_it->sync_label; |
522 content_description->AddStream(stream_param); | 466 content_description->AddStream(stream_param); |
523 | 467 |
524 // Store the new StreamParams in current_streams. | 468 // Store the new StreamParams in current_streams. |
525 // This is necessary so that we can use the CNAME for other media types. | 469 // This is necessary so that we can use the CNAME for other media types. |
526 current_streams->push_back(stream_param); | 470 current_streams->push_back(stream_param); |
527 } else { | 471 } else { |
528 content_description->AddStream(*param); | 472 content_description->AddStream(*param); |
529 } | 473 } |
530 } | 474 } |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 if (secure_policy == SEC_REQUIRED) { | 698 if (secure_policy == SEC_REQUIRED) { |
755 offer->set_crypto_required(CT_SDES); | 699 offer->set_crypto_required(CT_SDES); |
756 } | 700 } |
757 offer->set_rtcp_mux(options.rtcp_mux_enabled); | 701 offer->set_rtcp_mux(options.rtcp_mux_enabled); |
758 if (offer->type() == cricket::MEDIA_TYPE_VIDEO) { | 702 if (offer->type() == cricket::MEDIA_TYPE_VIDEO) { |
759 offer->set_rtcp_reduced_size(true); | 703 offer->set_rtcp_reduced_size(true); |
760 } | 704 } |
761 offer->set_multistream(options.is_muc); | 705 offer->set_multistream(options.is_muc); |
762 offer->set_rtp_header_extensions(rtp_extensions); | 706 offer->set_rtp_header_extensions(rtp_extensions); |
763 | 707 |
764 if (!AddStreamParams( | 708 if (!AddStreamParams(offer->type(), options, current_streams, offer, |
765 offer->type(), options.streams, current_streams, | 709 add_legacy_stream)) { |
766 offer, add_legacy_stream)) { | |
767 return false; | 710 return false; |
768 } | 711 } |
769 | 712 |
770 #ifdef HAVE_SRTP | 713 #ifdef HAVE_SRTP |
771 if (secure_policy != SEC_DISABLED) { | 714 if (secure_policy != SEC_DISABLED) { |
772 if (current_cryptos) { | 715 if (current_cryptos) { |
773 AddMediaCryptos(*current_cryptos, offer); | 716 AddMediaCryptos(*current_cryptos, offer); |
774 } | 717 } |
775 if (offer->cryptos().empty()) { | 718 if (offer->cryptos().empty()) { |
776 if (!CreateMediaCryptos(crypto_suites, offer)) { | 719 if (!CreateMediaCryptos(crypto_suites, offer)) { |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 } | 1016 } |
1074 answer->AddCrypto(crypto); | 1017 answer->AddCrypto(crypto); |
1075 } | 1018 } |
1076 } | 1019 } |
1077 | 1020 |
1078 if (answer->cryptos().empty() && | 1021 if (answer->cryptos().empty() && |
1079 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) { | 1022 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) { |
1080 return false; | 1023 return false; |
1081 } | 1024 } |
1082 | 1025 |
1083 if (!AddStreamParams( | 1026 if (!AddStreamParams(answer->type(), options, current_streams, answer, |
1084 answer->type(), options.streams, current_streams, | 1027 add_legacy_stream)) { |
1085 answer, add_legacy_stream)) { | |
1086 return false; // Something went seriously wrong. | 1028 return false; // Something went seriously wrong. |
1087 } | 1029 } |
1088 | 1030 |
1089 // Make sure the answer media content direction is per default set as | 1031 // Make sure the answer media content direction is per default set as |
1090 // described in RFC3264 section 6.1. | 1032 // described in RFC3264 section 6.1. |
1091 switch (offer->direction()) { | 1033 switch (offer->direction()) { |
1092 case MD_INACTIVE: | 1034 case MD_INACTIVE: |
1093 answer->set_direction(MD_INACTIVE); | 1035 answer->set_direction(MD_INACTIVE); |
1094 break; | 1036 break; |
1095 case MD_SENDONLY: | 1037 case MD_SENDONLY: |
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2038 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); | 1980 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); |
2039 } | 1981 } |
2040 | 1982 |
2041 const DataContentDescription* GetFirstDataContentDescription( | 1983 const DataContentDescription* GetFirstDataContentDescription( |
2042 const SessionDescription* sdesc) { | 1984 const SessionDescription* sdesc) { |
2043 return static_cast<const DataContentDescription*>( | 1985 return static_cast<const DataContentDescription*>( |
2044 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); | 1986 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); |
2045 } | 1987 } |
2046 | 1988 |
2047 } // namespace cricket | 1989 } // namespace cricket |
OLD | NEW |