| OLD | NEW |
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2014 Google Inc. | 3 * Copyright 2014 Google Inc. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
| 9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { | 236 if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { |
| 237 LOG(LS_ERROR) | 237 LOG(LS_ERROR) |
| 238 << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " | 238 << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " |
| 239 << sp.ToString(); | 239 << sp.ToString(); |
| 240 return false; | 240 return false; |
| 241 } | 241 } |
| 242 | 242 |
| 243 return true; | 243 return true; |
| 244 } | 244 } |
| 245 | 245 |
| 246 static std::string RtpExtensionsToString( | |
| 247 const std::vector<RtpHeaderExtension>& extensions) { | |
| 248 std::stringstream out; | |
| 249 out << '{'; | |
| 250 for (size_t i = 0; i < extensions.size(); ++i) { | |
| 251 out << "{" << extensions[i].uri << ": " << extensions[i].id << "}"; | |
| 252 if (i != extensions.size() - 1) { | |
| 253 out << ", "; | |
| 254 } | |
| 255 } | |
| 256 out << '}'; | |
| 257 return out.str(); | |
| 258 } | |
| 259 | |
| 260 inline const webrtc::RtpExtension* FindHeaderExtension( | 246 inline const webrtc::RtpExtension* FindHeaderExtension( |
| 261 const std::vector<webrtc::RtpExtension>& extensions, | 247 const std::vector<webrtc::RtpExtension>& extensions, |
| 262 const std::string& name) { | 248 const std::string& name) { |
| 263 for (const auto& kv : extensions) { | 249 for (const auto& kv : extensions) { |
| 264 if (kv.name == name) { | 250 if (kv.name == name) { |
| 265 return &kv; | 251 return &kv; |
| 266 } | 252 } |
| 267 } | 253 } |
| 268 return NULL; | 254 return NULL; |
| 269 } | 255 } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 VideoCodec* matching_codec) { | 349 VideoCodec* matching_codec) { |
| 364 for (size_t i = 0; i < codecs.size(); ++i) { | 350 for (size_t i = 0; i < codecs.size(); ++i) { |
| 365 if (requested_codec.Matches(codecs[i])) { | 351 if (requested_codec.Matches(codecs[i])) { |
| 366 *matching_codec = codecs[i]; | 352 *matching_codec = codecs[i]; |
| 367 return true; | 353 return true; |
| 368 } | 354 } |
| 369 } | 355 } |
| 370 return false; | 356 return false; |
| 371 } | 357 } |
| 372 | 358 |
| 373 static bool ValidateRtpHeaderExtensionIds( | |
| 374 const std::vector<RtpHeaderExtension>& extensions) { | |
| 375 std::set<int> extensions_used; | |
| 376 for (size_t i = 0; i < extensions.size(); ++i) { | |
| 377 if (extensions[i].id <= 0 || extensions[i].id >= 15 || | |
| 378 !extensions_used.insert(extensions[i].id).second) { | |
| 379 LOG(LS_ERROR) << "RTP extensions are with incorrect or duplicate ids."; | |
| 380 return false; | |
| 381 } | |
| 382 } | |
| 383 return true; | |
| 384 } | |
| 385 | |
| 386 static bool CompareRtpHeaderExtensionIds( | |
| 387 const webrtc::RtpExtension& extension1, | |
| 388 const webrtc::RtpExtension& extension2) { | |
| 389 // Sorting on ID is sufficient, more than one extension per ID is unsupported. | |
| 390 return extension1.id > extension2.id; | |
| 391 } | |
| 392 | |
| 393 static std::vector<webrtc::RtpExtension> FilterRtpExtensions( | |
| 394 const std::vector<RtpHeaderExtension>& extensions) { | |
| 395 std::vector<webrtc::RtpExtension> webrtc_extensions; | |
| 396 for (size_t i = 0; i < extensions.size(); ++i) { | |
| 397 // Unsupported extensions will be ignored. | |
| 398 if (webrtc::RtpExtension::IsSupportedForVideo(extensions[i].uri)) { | |
| 399 webrtc_extensions.push_back(webrtc::RtpExtension( | |
| 400 extensions[i].uri, extensions[i].id)); | |
| 401 } else { | |
| 402 LOG(LS_WARNING) << "Unsupported RTP extension: " << extensions[i].uri; | |
| 403 } | |
| 404 } | |
| 405 | |
| 406 // Sort filtered headers to make sure that they can later be compared | |
| 407 // regardless of in which order they were entered. | |
| 408 std::sort(webrtc_extensions.begin(), webrtc_extensions.end(), | |
| 409 CompareRtpHeaderExtensionIds); | |
| 410 return webrtc_extensions; | |
| 411 } | |
| 412 | |
| 413 static bool RtpExtensionsHaveChanged( | |
| 414 const std::vector<webrtc::RtpExtension>& before, | |
| 415 const std::vector<webrtc::RtpExtension>& after) { | |
| 416 if (before.size() != after.size()) | |
| 417 return true; | |
| 418 for (size_t i = 0; i < before.size(); ++i) { | |
| 419 if (before[i].id != after[i].id) | |
| 420 return true; | |
| 421 if (before[i].name != after[i].name) | |
| 422 return true; | |
| 423 } | |
| 424 return false; | |
| 425 } | |
| 426 | |
| 427 std::vector<webrtc::VideoStream> | 359 std::vector<webrtc::VideoStream> |
| 428 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateSimulcastVideoStreams( | 360 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateSimulcastVideoStreams( |
| 429 const VideoCodec& codec, | 361 const VideoCodec& codec, |
| 430 const VideoOptions& options, | 362 const VideoOptions& options, |
| 431 int max_bitrate_bps, | 363 int max_bitrate_bps, |
| 432 size_t num_streams) { | 364 size_t num_streams) { |
| 433 int max_qp = kDefaultQpMax; | 365 int max_qp = kDefaultQpMax; |
| 434 codec.GetParam(kCodecParamMaxQuantization, &max_qp); | 366 codec.GetParam(kCodecParamMaxQuantization, &max_qp); |
| 435 | 367 |
| 436 return GetSimulcastConfig( | 368 return GetSimulcastConfig( |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 849 before[i].codec.preference = 0; | 781 before[i].codec.preference = 0; |
| 850 after[i].codec.preference = 0; | 782 after[i].codec.preference = 0; |
| 851 if (before[i] != after[i]) { | 783 if (before[i] != after[i]) { |
| 852 return true; | 784 return true; |
| 853 } | 785 } |
| 854 } | 786 } |
| 855 return false; | 787 return false; |
| 856 } | 788 } |
| 857 | 789 |
| 858 bool WebRtcVideoChannel2::SetSendParameters(const VideoSendParameters& params) { | 790 bool WebRtcVideoChannel2::SetSendParameters(const VideoSendParameters& params) { |
| 791 LOG(LS_INFO) << "SetSendParameters: " << params.ToString(); |
| 859 // TODO(pbos): Refactor this to only recreate the send streams once | 792 // TODO(pbos): Refactor this to only recreate the send streams once |
| 860 // instead of 4 times. | 793 // instead of 4 times. |
| 861 return (SetSendCodecs(params.codecs) && | 794 return (SetSendCodecs(params.codecs) && |
| 862 SetSendRtpHeaderExtensions(params.extensions) && | 795 SetSendRtpHeaderExtensions(params.extensions) && |
| 863 SetMaxSendBandwidth(params.max_bandwidth_bps) && | 796 SetMaxSendBandwidth(params.max_bandwidth_bps) && |
| 864 SetOptions(params.options)); | 797 SetOptions(params.options)); |
| 865 } | 798 } |
| 866 | 799 |
| 867 bool WebRtcVideoChannel2::SetRecvParameters(const VideoRecvParameters& params) { | 800 bool WebRtcVideoChannel2::SetRecvParameters(const VideoRecvParameters& params) { |
| 801 LOG(LS_INFO) << "SetRecvParameters: " << params.ToString(); |
| 868 // TODO(pbos): Refactor this to only recreate the recv streams once | 802 // TODO(pbos): Refactor this to only recreate the recv streams once |
| 869 // instead of twice. | 803 // instead of twice. |
| 870 return (SetRecvCodecs(params.codecs) && | 804 return (SetRecvCodecs(params.codecs) && |
| 871 SetRecvRtpHeaderExtensions(params.extensions)); | 805 SetRecvRtpHeaderExtensions(params.extensions)); |
| 872 } | 806 } |
| 873 | 807 |
| 874 std::string WebRtcVideoChannel2::CodecSettingsVectorToString( | 808 std::string WebRtcVideoChannel2::CodecSettingsVectorToString( |
| 875 const std::vector<VideoCodecSettings>& codecs) { | 809 const std::vector<VideoCodecSettings>& codecs) { |
| 876 std::stringstream out; | 810 std::stringstream out; |
| 877 out << '{'; | 811 out << '{'; |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1500 return false; | 1434 return false; |
| 1501 } | 1435 } |
| 1502 | 1436 |
| 1503 send_streams_[ssrc]->MuteStream(mute); | 1437 send_streams_[ssrc]->MuteStream(mute); |
| 1504 return true; | 1438 return true; |
| 1505 } | 1439 } |
| 1506 | 1440 |
| 1507 bool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( | 1441 bool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( |
| 1508 const std::vector<RtpHeaderExtension>& extensions) { | 1442 const std::vector<RtpHeaderExtension>& extensions) { |
| 1509 TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvRtpHeaderExtensions"); | 1443 TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvRtpHeaderExtensions"); |
| 1510 LOG(LS_INFO) << "SetRecvRtpHeaderExtensions: " | 1444 if (!ValidateRtpExtensions(extensions)) { |
| 1511 << RtpExtensionsToString(extensions); | |
| 1512 if (!ValidateRtpHeaderExtensionIds(extensions)) | |
| 1513 return false; | 1445 return false; |
| 1514 | 1446 } |
| 1515 std::vector<webrtc::RtpExtension> filtered_extensions = | 1447 std::vector<webrtc::RtpExtension> filtered_extensions = FilterRtpExtensions( |
| 1516 FilterRtpExtensions(extensions); | 1448 extensions, webrtc::RtpExtension::IsSupportedForVideo, false); |
| 1517 if (!RtpExtensionsHaveChanged(recv_rtp_extensions_, filtered_extensions)) { | 1449 if (recv_rtp_extensions_ == filtered_extensions) { |
| 1518 LOG(LS_INFO) << "Ignoring call to SetRecvRtpHeaderExtensions because " | 1450 LOG(LS_INFO) << "Ignoring call to SetRecvRtpHeaderExtensions because " |
| 1519 "header extensions haven't changed."; | 1451 "header extensions haven't changed."; |
| 1520 return true; | 1452 return true; |
| 1521 } | 1453 } |
| 1522 | 1454 recv_rtp_extensions_.swap(filtered_extensions); |
| 1523 recv_rtp_extensions_ = filtered_extensions; | |
| 1524 | 1455 |
| 1525 rtc::CritScope stream_lock(&stream_crit_); | 1456 rtc::CritScope stream_lock(&stream_crit_); |
| 1526 for (std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = | 1457 for (std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = |
| 1527 receive_streams_.begin(); | 1458 receive_streams_.begin(); |
| 1528 it != receive_streams_.end(); ++it) { | 1459 it != receive_streams_.end(); ++it) { |
| 1529 it->second->SetRtpExtensions(recv_rtp_extensions_); | 1460 it->second->SetRtpExtensions(recv_rtp_extensions_); |
| 1530 } | 1461 } |
| 1531 return true; | 1462 return true; |
| 1532 } | 1463 } |
| 1533 | 1464 |
| 1534 bool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( | 1465 bool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( |
| 1535 const std::vector<RtpHeaderExtension>& extensions) { | 1466 const std::vector<RtpHeaderExtension>& extensions) { |
| 1536 TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendRtpHeaderExtensions"); | 1467 TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendRtpHeaderExtensions"); |
| 1537 LOG(LS_INFO) << "SetSendRtpHeaderExtensions: " | 1468 if (!ValidateRtpExtensions(extensions)) { |
| 1538 << RtpExtensionsToString(extensions); | |
| 1539 if (!ValidateRtpHeaderExtensionIds(extensions)) | |
| 1540 return false; | 1469 return false; |
| 1541 | 1470 } |
| 1542 std::vector<webrtc::RtpExtension> filtered_extensions = | 1471 std::vector<webrtc::RtpExtension> filtered_extensions = FilterRtpExtensions( |
| 1543 FilterRtpExtensions(FilterRedundantRtpExtensions( | 1472 extensions, webrtc::RtpExtension::IsSupportedForVideo, true); |
| 1544 extensions, kBweExtensionPriorities, kBweExtensionPrioritiesLength)); | 1473 if (send_rtp_extensions_ == filtered_extensions) { |
| 1545 if (!RtpExtensionsHaveChanged(send_rtp_extensions_, filtered_extensions)) { | 1474 LOG(LS_INFO) << "Ignoring call to SetRecvRtpHeaderExtensions because " |
| 1546 LOG(LS_INFO) << "Ignoring call to SetSendRtpHeaderExtensions because " | |
| 1547 "header extensions haven't changed."; | 1475 "header extensions haven't changed."; |
| 1548 return true; | 1476 return true; |
| 1549 } | 1477 } |
| 1550 | 1478 send_rtp_extensions_.swap(filtered_extensions); |
| 1551 send_rtp_extensions_ = filtered_extensions; | |
| 1552 | 1479 |
| 1553 const webrtc::RtpExtension* cvo_extension = FindHeaderExtension( | 1480 const webrtc::RtpExtension* cvo_extension = FindHeaderExtension( |
| 1554 send_rtp_extensions_, kRtpVideoRotationHeaderExtension); | 1481 send_rtp_extensions_, kRtpVideoRotationHeaderExtension); |
| 1555 | 1482 |
| 1556 rtc::CritScope stream_lock(&stream_crit_); | 1483 rtc::CritScope stream_lock(&stream_crit_); |
| 1557 for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = | 1484 for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = |
| 1558 send_streams_.begin(); | 1485 send_streams_.begin(); |
| 1559 it != send_streams_.end(); ++it) { | 1486 it != send_streams_.end(); ++it) { |
| 1560 it->second->SetRtpExtensions(send_rtp_extensions_); | 1487 it->second->SetRtpExtensions(send_rtp_extensions_); |
| 1561 it->second->SetApplyRotation(!cvo_extension); | 1488 it->second->SetApplyRotation(!cvo_extension); |
| (...skipping 1194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2756 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; | 2683 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; |
| 2757 } | 2684 } |
| 2758 } | 2685 } |
| 2759 | 2686 |
| 2760 return video_codecs; | 2687 return video_codecs; |
| 2761 } | 2688 } |
| 2762 | 2689 |
| 2763 } // namespace cricket | 2690 } // namespace cricket |
| 2764 | 2691 |
| 2765 #endif // HAVE_WEBRTC_VIDEO | 2692 #endif // HAVE_WEBRTC_VIDEO |
| OLD | NEW |