OLD | NEW |
---|---|
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2004 Google Inc. | 3 * Copyright 2004 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 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
892 if (!writable_) | 892 if (!writable_) |
893 return; | 893 return; |
894 | 894 |
895 LOG(LS_INFO) << "Channel socket not writable (" | 895 LOG(LS_INFO) << "Channel socket not writable (" |
896 << transport_channel_->content_name() << ", " | 896 << transport_channel_->content_name() << ", " |
897 << transport_channel_->component() << ")"; | 897 << transport_channel_->component() << ")"; |
898 writable_ = false; | 898 writable_ = false; |
899 ChangeState(); | 899 ChangeState(); |
900 } | 900 } |
901 | 901 |
902 bool BaseChannel::SetRtpTransportParameters_w( | |
903 const MediaContentDescription* content, | |
904 ContentAction action, | |
905 ContentSource src, | |
906 std::string* error_desc) { | |
907 // Cache secure_required_ for belt and suspenders check on SendPacket | |
908 set_secure_required(content->crypto_required() != CT_NONE); | |
909 if (!SetSrtp_w(content->cryptos(), action, src, error_desc)) { | |
910 return false; | |
pbos-webrtc
2015/07/14 08:25:01
Don't you need SafeSetError anymore? (I never unde
pthatcher1
2015/07/16 10:47:11
SetSrtp_w call SafeSetError.
| |
911 } | |
912 | |
913 if (!SetRtcpMux_w(content->rtcp_mux(), action, src, error_desc)) { | |
914 return false; | |
915 } | |
916 return true; | |
917 } | |
918 | |
902 // |dtls| will be set to true if DTLS is active for transport channel and | 919 // |dtls| will be set to true if DTLS is active for transport channel and |
903 // crypto is empty. | 920 // crypto is empty. |
904 bool BaseChannel::CheckSrtpConfig(const std::vector<CryptoParams>& cryptos, | 921 bool BaseChannel::CheckSrtpConfig(const std::vector<CryptoParams>& cryptos, |
905 bool* dtls, | 922 bool* dtls, |
906 std::string* error_desc) { | 923 std::string* error_desc) { |
907 *dtls = transport_channel_->IsDtlsActive(); | 924 *dtls = transport_channel_->IsDtlsActive(); |
908 if (*dtls && !cryptos.empty()) { | 925 if (*dtls && !cryptos.empty()) { |
909 SafeSetError("Cryptos must be empty when DTLS is active.", | 926 SafeSetError("Cryptos must be empty when DTLS is active.", |
910 error_desc); | 927 error_desc); |
911 return false; | 928 return false; |
912 } | 929 } |
913 return true; | 930 return true; |
914 } | 931 } |
915 | 932 |
916 bool BaseChannel::SetRecvRtpHeaderExtensions_w( | |
917 const MediaContentDescription* content, | |
918 MediaChannel* media_channel, | |
919 std::string* error_desc) { | |
920 if (content->rtp_header_extensions_set()) { | |
921 if (!media_channel->SetRecvRtpHeaderExtensions( | |
922 content->rtp_header_extensions())) { | |
923 std::ostringstream desc; | |
924 desc << "Failed to set receive rtp header extensions for " | |
925 << MediaTypeToString(content->type()) << " content."; | |
926 SafeSetError(desc.str(), error_desc); | |
927 return false; | |
928 } | |
929 } | |
930 return true; | |
931 } | |
932 | |
933 bool BaseChannel::SetSendRtpHeaderExtensions_w( | |
934 const MediaContentDescription* content, | |
935 MediaChannel* media_channel, | |
936 std::string* error_desc) { | |
937 if (content->rtp_header_extensions_set()) { | |
938 if (!media_channel->SetSendRtpHeaderExtensions( | |
939 content->rtp_header_extensions())) { | |
940 std::ostringstream desc; | |
941 desc << "Failed to set send rtp header extensions for " | |
942 << MediaTypeToString(content->type()) << " content."; | |
943 SafeSetError(desc.str(), error_desc); | |
944 return false; | |
945 } else { | |
946 MaybeCacheRtpAbsSendTimeHeaderExtension(content->rtp_header_extensions()); | |
947 } | |
948 } | |
949 return true; | |
950 } | |
951 | |
952 bool BaseChannel::SetSrtp_w(const std::vector<CryptoParams>& cryptos, | 933 bool BaseChannel::SetSrtp_w(const std::vector<CryptoParams>& cryptos, |
953 ContentAction action, | 934 ContentAction action, |
954 ContentSource src, | 935 ContentSource src, |
955 std::string* error_desc) { | 936 std::string* error_desc) { |
956 if (action == CA_UPDATE) { | 937 if (action == CA_UPDATE) { |
957 // no crypto params. | 938 // no crypto params. |
958 return true; | 939 return true; |
959 } | 940 } |
960 bool ret = false; | 941 bool ret = false; |
961 bool dtls = false; | 942 bool dtls = false; |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1203 desc << "Failed to add remote stream ssrc: " << it->first_ssrc(); | 1184 desc << "Failed to add remote stream ssrc: " << it->first_ssrc(); |
1204 SafeSetError(desc.str(), error_desc); | 1185 SafeSetError(desc.str(), error_desc); |
1205 ret = false; | 1186 ret = false; |
1206 } | 1187 } |
1207 } | 1188 } |
1208 } | 1189 } |
1209 remote_streams_ = streams; | 1190 remote_streams_ = streams; |
1210 return ret; | 1191 return ret; |
1211 } | 1192 } |
1212 | 1193 |
1213 bool BaseChannel::SetBaseLocalContent_w(const MediaContentDescription* content, | |
1214 ContentAction action, | |
1215 std::string* error_desc) { | |
1216 // Cache secure_required_ for belt and suspenders check on SendPacket | |
1217 secure_required_ = content->crypto_required() != CT_NONE; | |
1218 // Set local RTP header extensions. | |
1219 bool ret = SetRecvRtpHeaderExtensions_w(content, media_channel(), error_desc); | |
1220 // Set local SRTP parameters (what we will encrypt with). | |
1221 ret &= SetSrtp_w(content->cryptos(), action, CS_LOCAL, error_desc); | |
1222 // Set local RTCP mux parameters. | |
1223 ret &= SetRtcpMux_w(content->rtcp_mux(), action, CS_LOCAL, error_desc); | |
1224 | |
1225 // Call UpdateLocalStreams_w last to make sure as many settings as possible | |
1226 // are already set when creating streams. | |
1227 ret &= UpdateLocalStreams_w(content->streams(), action, error_desc); | |
1228 set_local_content_direction(content->direction()); | |
1229 return ret; | |
1230 } | |
1231 | |
1232 bool BaseChannel::SetBaseRemoteContent_w(const MediaContentDescription* content, | |
1233 ContentAction action, | |
1234 std::string* error_desc) { | |
1235 // Set remote RTP header extensions. | |
1236 bool ret = SetSendRtpHeaderExtensions_w(content, media_channel(), error_desc); | |
1237 // Set remote SRTP parameters (what the other side will encrypt with). | |
1238 ret &= SetSrtp_w(content->cryptos(), action, CS_REMOTE, error_desc); | |
1239 // Set remote RTCP mux parameters. | |
1240 ret &= SetRtcpMux_w(content->rtcp_mux(), action, CS_REMOTE, error_desc); | |
1241 if (!media_channel()->SetMaxSendBandwidth(content->bandwidth())) { | |
1242 std::ostringstream desc; | |
1243 desc << "Failed to set max send bandwidth for " | |
1244 << MediaTypeToString(content->type()) << " content."; | |
1245 SafeSetError(desc.str(), error_desc); | |
1246 ret = false; | |
1247 } | |
1248 | |
1249 // Call UpdateRemoteStreams_w last to make sure as many settings as possible | |
1250 // are already set when creating streams. | |
1251 ret &= UpdateRemoteStreams_w(content->streams(), action, error_desc); | |
1252 set_remote_content_direction(content->direction()); | |
1253 return ret; | |
1254 } | |
1255 | |
1256 void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension( | 1194 void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension( |
1257 const std::vector<RtpHeaderExtension>& extensions) { | 1195 const std::vector<RtpHeaderExtension>& extensions) { |
1258 const RtpHeaderExtension* send_time_extension = | 1196 const RtpHeaderExtension* send_time_extension = |
1259 FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); | 1197 FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); |
1260 rtp_abs_sendtime_extn_id_ = | 1198 rtp_abs_sendtime_extn_id_ = |
1261 send_time_extension ? send_time_extension->id : -1; | 1199 send_time_extension ? send_time_extension->id : -1; |
1262 } | 1200 } |
1263 | 1201 |
1264 void BaseChannel::OnMessage(rtc::Message *pmsg) { | 1202 void BaseChannel::OnMessage(rtc::Message *pmsg) { |
1265 switch (pmsg->message_id) { | 1203 switch (pmsg->message_id) { |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1495 LOG(LS_INFO) << "Setting local voice description"; | 1433 LOG(LS_INFO) << "Setting local voice description"; |
1496 | 1434 |
1497 const AudioContentDescription* audio = | 1435 const AudioContentDescription* audio = |
1498 static_cast<const AudioContentDescription*>(content); | 1436 static_cast<const AudioContentDescription*>(content); |
1499 ASSERT(audio != NULL); | 1437 ASSERT(audio != NULL); |
1500 if (!audio) { | 1438 if (!audio) { |
1501 SafeSetError("Can't find audio content in local description.", error_desc); | 1439 SafeSetError("Can't find audio content in local description.", error_desc); |
1502 return false; | 1440 return false; |
1503 } | 1441 } |
1504 | 1442 |
1505 bool ret = SetBaseLocalContent_w(content, action, error_desc); | 1443 // CA_UPDATE is only used by the Harmony library to update send |
1506 // Set local audio codecs (what we want to receive). | 1444 // streams. |
1507 // TODO(whyuan): Change action != CA_UPDATE to !audio->partial() when partial | 1445 // TODO(pthatcher): Move this logic up into the Harmony library and |
1508 // is set properly. | 1446 // remove CA_UPDATE. |
1509 if (action != CA_UPDATE || audio->has_codecs()) { | 1447 if (action == CA_UPDATE && |
1510 if (!media_channel()->SetRecvCodecs(audio->codecs())) { | 1448 !UpdateLocalStreams_w(content->streams(), action, error_desc)) { |
1511 SafeSetError("Failed to set audio receive codecs.", error_desc); | 1449 SafeSetError("Failed to set local audio description send streams.", |
1512 ret = false; | 1450 error_desc); |
1513 } | 1451 return false; |
1514 } | 1452 } |
1515 | 1453 |
1516 // If everything worked, see if we can start receiving. | 1454 if (!SetRtpTransportParameters_w(content, action, CS_LOCAL, error_desc)) { |
1517 if (ret) { | 1455 return false; |
1518 std::vector<AudioCodec>::const_iterator it = audio->codecs().begin(); | 1456 } |
1519 for (; it != audio->codecs().end(); ++it) { | 1457 |
1520 bundle_filter()->AddPayloadType(it->id); | 1458 AudioRecvParameters recv_params; |
1521 } | 1459 recv_params.codecs = audio->codecs(); |
1522 ChangeState(); | 1460 // TODO(pthatcher): See if we really need |
1461 // rtp_header_extensions_set() and remove it if we don't. | |
1462 if (audio->rtp_header_extensions_set()) { | |
1463 recv_params.extensions = audio->rtp_header_extensions(); | |
1523 } else { | 1464 } else { |
1524 LOG(LS_WARNING) << "Failed to set local voice description"; | 1465 // Just maintain the last set of header extensions. |
1466 recv_params.extensions = last_recv_params_.extensions; | |
1525 } | 1467 } |
1526 return ret; | 1468 |
1469 if (!media_channel()->SetRecvParameters(recv_params)) { | |
1470 SafeSetError("Failed to set local video description recv parameters.", | |
1471 error_desc); | |
1472 return false; | |
1473 } | |
1474 | |
1475 // TODO(pthatcher): Move local streams into AudioSendParameters, and | |
1476 // only give it to the media channel once we have a remote | |
1477 // description too (without a remote description, we won't be able | |
1478 // to send them anyway). | |
1479 if (!UpdateLocalStreams_w(audio->streams(), action, error_desc)) { | |
1480 SafeSetError("Failed to set local audio description streams.", error_desc); | |
1481 return false; | |
1482 } | |
1483 | |
1484 for (const AudioCodec& codec : audio->codecs()) { | |
1485 bundle_filter()->AddPayloadType(codec.id); | |
1486 } | |
1487 | |
1488 set_local_content_direction(content->direction()); | |
1489 ChangeState(); | |
1490 return true; | |
1527 } | 1491 } |
1528 | 1492 |
1529 bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content, | 1493 bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content, |
1530 ContentAction action, | 1494 ContentAction action, |
1531 std::string* error_desc) { | 1495 std::string* error_desc) { |
1532 ASSERT(worker_thread() == rtc::Thread::Current()); | 1496 ASSERT(worker_thread() == rtc::Thread::Current()); |
1533 LOG(LS_INFO) << "Setting remote voice description"; | 1497 LOG(LS_INFO) << "Setting remote voice description"; |
1534 | 1498 |
1535 const AudioContentDescription* audio = | 1499 const AudioContentDescription* audio = |
1536 static_cast<const AudioContentDescription*>(content); | 1500 static_cast<const AudioContentDescription*>(content); |
1537 ASSERT(audio != NULL); | 1501 ASSERT(audio != NULL); |
1538 if (!audio) { | 1502 if (!audio) { |
1539 SafeSetError("Can't find audio content in remote description.", error_desc); | 1503 SafeSetError("Can't find audio content in remote description.", error_desc); |
1540 return false; | 1504 return false; |
1541 } | 1505 } |
1542 | 1506 |
1543 bool ret = true; | 1507 // CA_UPDATE is only used by the Harmony library to update send |
1544 // Set remote video codecs (what the other side wants to receive). | 1508 // codecs and receive streams. |
1545 if (action != CA_UPDATE || audio->has_codecs()) { | 1509 // TODO(pthatcher): Move this logic up into the Harmony library and |
1546 if (!media_channel()->SetSendCodecs(audio->codecs())) { | 1510 // remove CA_UPDATE. |
1547 SafeSetError("Failed to set audio send codecs.", error_desc); | 1511 if (action == CA_UPDATE) { |
1548 ret = false; | 1512 if (audio->has_codecs() && |
1513 !media_channel()->SetSendCodecs(audio->codecs())) { | |
1514 SafeSetError("Failed to set remote audio description send codecs.", | |
1515 error_desc); | |
1516 return false; | |
1549 } | 1517 } |
1518 if (!UpdateRemoteStreams_w(content->streams(), action, error_desc)) { | |
1519 SafeSetError("Failed to set remote audio description receive streams.", | |
1520 error_desc); | |
1521 return false; | |
1522 } | |
1523 return true; | |
1550 } | 1524 } |
1551 | 1525 |
1552 ret &= SetBaseRemoteContent_w(content, action, error_desc); | 1526 if (!SetRtpTransportParameters_w(content, action, CS_REMOTE, error_desc)) { |
1553 | 1527 return false; |
1554 if (action != CA_UPDATE) { | |
1555 // Tweak our audio processing settings, if needed. | |
1556 AudioOptions audio_options; | |
1557 if (!media_channel()->GetOptions(&audio_options)) { | |
1558 LOG(LS_WARNING) << "Can not set audio options from on remote content."; | |
1559 } else { | |
1560 if (audio->conference_mode()) { | |
1561 audio_options.conference_mode.Set(true); | |
1562 } | |
1563 if (audio->agc_minus_10db()) { | |
1564 audio_options.adjust_agc_delta.Set(kAgcMinus10db); | |
1565 } | |
1566 if (!media_channel()->SetOptions(audio_options)) { | |
1567 // Log an error on failure, but don't abort the call. | |
1568 LOG(LS_ERROR) << "Failed to set voice channel options"; | |
1569 } | |
1570 } | |
1571 } | 1528 } |
1572 | 1529 |
1573 // If everything worked, see if we can start sending. | 1530 AudioSendParameters send_params; |
1574 if (ret) { | 1531 send_params.codecs = audio->codecs(); |
1575 ChangeState(); | 1532 // TODO(pthatcher): See if we really need |
1533 // rtp_header_extensions_set() and remove it if we don't. | |
1534 if (audio->rtp_header_extensions_set()) { | |
1535 send_params.extensions = audio->rtp_header_extensions(); | |
1576 } else { | 1536 } else { |
1577 LOG(LS_WARNING) << "Failed to set remote voice description"; | 1537 // Just maintain the last set of header extensions. |
1538 send_params.extensions = last_send_params_.extensions; | |
1578 } | 1539 } |
1579 return ret; | 1540 send_params.max_bandwidth_bps = audio->bandwidth(); |
1541 send_params.options = last_send_params_.options; | |
1542 if (audio->conference_mode()) { | |
1543 send_params.options.conference_mode.Set(true); | |
1544 } | |
1545 if (audio->agc_minus_10db()) { | |
1546 send_params.options.adjust_agc_delta.Set(kAgcMinus10db); | |
1547 } | |
1548 if (!media_channel()->SetSendParameters(send_params)) { | |
1549 SafeSetError("Failed to set remote audio description send parameters.", | |
1550 error_desc); | |
1551 return false; | |
1552 } | |
1553 last_send_params_ = send_params; | |
1554 | |
1555 // TODO(pthatcher): Move remote streams into AudioRecvParameters, | |
1556 // and only give it to the media channel once we have a local | |
1557 // description too (without a local description, we won't be able to | |
1558 // recv them anyway). | |
1559 if (!UpdateRemoteStreams_w(audio->streams(), action, error_desc)) { | |
1560 LOG(LS_WARNING) << "Failed to set remote audio description receive streams"; | |
1561 return false; | |
1562 } | |
1563 | |
1564 set_remote_content_direction(content->direction()); | |
1565 ChangeState(); | |
1566 return true; | |
1580 } | 1567 } |
1581 | 1568 |
1582 bool VoiceChannel::SetRingbackTone_w(const void* buf, int len) { | 1569 bool VoiceChannel::SetRingbackTone_w(const void* buf, int len) { |
1583 ASSERT(worker_thread() == rtc::Thread::Current()); | 1570 ASSERT(worker_thread() == rtc::Thread::Current()); |
1584 return media_channel()->SetRingbackTone(static_cast<const char*>(buf), len); | 1571 return media_channel()->SetRingbackTone(static_cast<const char*>(buf), len); |
1585 } | 1572 } |
1586 | 1573 |
1587 bool VoiceChannel::PlayRingbackTone_w(uint32 ssrc, bool play, bool loop) { | 1574 bool VoiceChannel::PlayRingbackTone_w(uint32 ssrc, bool play, bool loop) { |
1588 ASSERT(worker_thread() == rtc::Thread::Current()); | 1575 ASSERT(worker_thread() == rtc::Thread::Current()); |
1589 if (play) { | 1576 if (play) { |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1839 LOG(LS_INFO) << "Setting local video description"; | 1826 LOG(LS_INFO) << "Setting local video description"; |
1840 | 1827 |
1841 const VideoContentDescription* video = | 1828 const VideoContentDescription* video = |
1842 static_cast<const VideoContentDescription*>(content); | 1829 static_cast<const VideoContentDescription*>(content); |
1843 ASSERT(video != NULL); | 1830 ASSERT(video != NULL); |
1844 if (!video) { | 1831 if (!video) { |
1845 SafeSetError("Can't find video content in local description.", error_desc); | 1832 SafeSetError("Can't find video content in local description.", error_desc); |
1846 return false; | 1833 return false; |
1847 } | 1834 } |
1848 | 1835 |
1849 bool ret = SetBaseLocalContent_w(content, action, error_desc); | 1836 // CA_UPDATE is only used by the Harmony library to update send streams. |
1850 // Set local video codecs (what we want to receive). | 1837 // TODO(pthatcher): Move this logic up into the Harmony library and |
1851 if (action != CA_UPDATE || video->has_codecs()) { | 1838 // remove CA_UPDATE. |
1852 if (!media_channel()->SetRecvCodecs(video->codecs())) { | 1839 if (action == CA_UPDATE && |
1853 SafeSetError("Failed to set video receive codecs.", error_desc); | 1840 !UpdateLocalStreams_w(content->streams(), action, error_desc)) { |
1854 ret = false; | 1841 SafeSetError("Failed to set local audio description send streams.", |
1855 } | 1842 error_desc); |
1843 return false; | |
1856 } | 1844 } |
1857 | 1845 |
1858 if (action != CA_UPDATE) { | 1846 if (!SetRtpTransportParameters_w(content, action, CS_LOCAL, error_desc)) { |
1859 VideoOptions video_options; | 1847 return false; |
1860 media_channel()->GetOptions(&video_options); | |
1861 video_options.buffered_mode_latency.Set(video->buffered_mode_latency()); | |
1862 | |
1863 if (!media_channel()->SetOptions(video_options)) { | |
1864 // Log an error on failure, but don't abort the call. | |
1865 LOG(LS_ERROR) << "Failed to set video channel options"; | |
1866 } | |
1867 } | 1848 } |
1868 | 1849 |
1869 // If everything worked, see if we can start receiving. | 1850 VideoRecvParameters recv_params; |
1870 if (ret) { | 1851 recv_params.codecs = video->codecs(); |
1871 std::vector<VideoCodec>::const_iterator it = video->codecs().begin(); | 1852 // TODO(pthatcher): See if we really need |
1872 for (; it != video->codecs().end(); ++it) { | 1853 // rtp_header_extensions_set() and remove it if we don't. |
1873 bundle_filter()->AddPayloadType(it->id); | 1854 if (video->rtp_header_extensions_set()) { |
1874 } | 1855 recv_params.extensions = video->rtp_header_extensions(); |
1875 ChangeState(); | |
1876 } else { | 1856 } else { |
1877 LOG(LS_WARNING) << "Failed to set local video description"; | 1857 // Just maintain the last set of header extensions. |
1858 recv_params.extensions = last_recv_params_.extensions; | |
1878 } | 1859 } |
1879 return ret; | 1860 |
1861 if (!media_channel()->SetRecvParameters(recv_params)) { | |
1862 SafeSetError("Failed to set local video description recv parameters.", | |
1863 error_desc); | |
1864 return false; | |
1865 } | |
1866 last_recv_params_ = recv_params; | |
1867 | |
1868 // TODO(pthatcher): Move local streams into VideoSendParameters, and | |
1869 // only give it to the media channel once we have a remote | |
1870 // description too (without a remote description, we won't be able | |
1871 // to send them anyway). | |
1872 if (!UpdateLocalStreams_w(video->streams(), action, error_desc)) { | |
1873 SafeSetError("Failed to set local video description streams.", error_desc); | |
1874 return false; | |
1875 } | |
1876 | |
1877 for (const VideoCodec& codec : video->codecs()) { | |
1878 bundle_filter()->AddPayloadType(codec.id); | |
1879 } | |
1880 | |
1881 set_local_content_direction(content->direction()); | |
1882 ChangeState(); | |
1883 return true; | |
1880 } | 1884 } |
1881 | 1885 |
1882 bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content, | 1886 bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content, |
1883 ContentAction action, | 1887 ContentAction action, |
1884 std::string* error_desc) { | 1888 std::string* error_desc) { |
1885 ASSERT(worker_thread() == rtc::Thread::Current()); | 1889 ASSERT(worker_thread() == rtc::Thread::Current()); |
1886 LOG(LS_INFO) << "Setting remote video description"; | 1890 LOG(LS_INFO) << "Setting remote video description"; |
1887 | 1891 |
1888 const VideoContentDescription* video = | 1892 const VideoContentDescription* video = |
1889 static_cast<const VideoContentDescription*>(content); | 1893 static_cast<const VideoContentDescription*>(content); |
1890 ASSERT(video != NULL); | 1894 ASSERT(video != NULL); |
1891 if (!video) { | 1895 if (!video) { |
1892 SafeSetError("Can't find video content in remote description.", error_desc); | 1896 SafeSetError("Can't find video content in remote description.", error_desc); |
1893 return false; | 1897 return false; |
1894 } | 1898 } |
1895 | 1899 |
1896 bool ret = true; | 1900 // CA_UPDATE is only used by the Harmony library to update send |
1897 // Set remote video codecs (what the other side wants to receive). | 1901 // codecs and receive streams. |
1898 if (action != CA_UPDATE || video->has_codecs()) { | 1902 // TODO(pthatcher): Move this logic up into the Harmony library and |
1899 if (!media_channel()->SetSendCodecs(video->codecs())) { | 1903 // remove CA_UPDATE. |
1900 SafeSetError("Failed to set video send codecs.", error_desc); | 1904 if (action == CA_UPDATE) { |
1901 ret = false; | 1905 if (video->has_codecs() && |
1906 !media_channel()->SetSendCodecs(video->codecs())) { | |
1907 SafeSetError("Failed to set remote video description send codecs.", | |
1908 error_desc); | |
1909 return false; | |
1902 } | 1910 } |
1911 if (!UpdateRemoteStreams_w(content->streams(), action, error_desc)) { | |
1912 SafeSetError("Failed to set remote video description receive streams.", | |
1913 error_desc); | |
1914 return false; | |
1915 } | |
1916 return true; | |
1903 } | 1917 } |
1904 | 1918 |
1905 ret &= SetBaseRemoteContent_w(content, action, error_desc); | 1919 if (!SetRtpTransportParameters_w(content, action, CS_REMOTE, error_desc)) { |
1906 | 1920 return false; |
1907 if (action != CA_UPDATE) { | |
1908 // Tweak our video processing settings, if needed. | |
1909 VideoOptions video_options; | |
1910 media_channel()->GetOptions(&video_options); | |
1911 if (video->conference_mode()) { | |
1912 video_options.conference_mode.Set(true); | |
1913 } | |
1914 video_options.buffered_mode_latency.Set(video->buffered_mode_latency()); | |
1915 | |
1916 if (!media_channel()->SetOptions(video_options)) { | |
1917 // Log an error on failure, but don't abort the call. | |
1918 LOG(LS_ERROR) << "Failed to set video channel options"; | |
1919 } | |
1920 } | 1921 } |
1921 | 1922 |
1922 // If everything worked, see if we can start sending. | 1923 VideoSendParameters send_params; |
1923 if (ret) { | 1924 send_params.codecs = video->codecs(); |
1924 ChangeState(); | 1925 // TODO(pthatcher): See if we really need |
1926 // rtp_header_extensions_set() and remove it if we don't. | |
1927 if (video->rtp_header_extensions_set()) { | |
1928 send_params.extensions = video->rtp_header_extensions(); | |
1925 } else { | 1929 } else { |
1926 LOG(LS_WARNING) << "Failed to set remote video description"; | 1930 // Just maintain the last set of header extensions. |
1931 send_params.extensions = last_send_params_.extensions; | |
1927 } | 1932 } |
1928 return ret; | 1933 send_params.max_bandwidth_bps = video->bandwidth(); |
1934 send_params.options = last_send_params_.options; | |
1935 if (video->conference_mode()) { | |
1936 send_params.options.conference_mode.Set(true); | |
1937 } | |
1938 if (!media_channel()->SetSendParameters(send_params)) { | |
1939 SafeSetError("Failed to set remote video description send parameters.", | |
1940 error_desc); | |
1941 return false; | |
1942 } | |
1943 last_send_params_ = send_params; | |
1944 | |
1945 if (video->rtp_header_extensions_set()) { | |
1946 MaybeCacheRtpAbsSendTimeHeaderExtension(video->rtp_header_extensions()); | |
1947 } | |
1948 | |
1949 // TODO(pthatcher): Move remote streams into VideoRecvParameters, | |
1950 // and only give it to the media channel once we have a local | |
1951 // description too (without a local description, we won't be able to | |
1952 // recv them anyway). | |
1953 if (!UpdateRemoteStreams_w(video->streams(), action, error_desc)) { | |
1954 LOG(LS_WARNING) << "Failed to set remote video description receive streams"; | |
1955 return false; | |
1956 } | |
1957 | |
1958 set_remote_content_direction(content->direction()); | |
1959 ChangeState(); | |
1960 return true; | |
1929 } | 1961 } |
1930 | 1962 |
1931 bool VideoChannel::ApplyViewRequest_w(const ViewRequest& request) { | 1963 bool VideoChannel::ApplyViewRequest_w(const ViewRequest& request) { |
1932 bool ret = true; | 1964 bool ret = true; |
1933 // Set the send format for each of the local streams. If the view request | 1965 // Set the send format for each of the local streams. If the view request |
1934 // does not contain a local stream, set its send format to 0x0, which will | 1966 // does not contain a local stream, set its send format to 0x0, which will |
1935 // drop all frames. | 1967 // drop all frames. |
1936 for (std::vector<StreamParams>::const_iterator it = local_streams().begin(); | 1968 for (std::vector<StreamParams>::const_iterator it = local_streams().begin(); |
1937 it != local_streams().end(); ++it) { | 1969 it != local_streams().end(); ++it) { |
1938 VideoFormat format(0, 0, 0, cricket::FOURCC_I420); | 1970 VideoFormat format(0, 0, 0, cricket::FOURCC_I420); |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2223 LOG(LS_INFO) << "Setting local data description"; | 2255 LOG(LS_INFO) << "Setting local data description"; |
2224 | 2256 |
2225 const DataContentDescription* data = | 2257 const DataContentDescription* data = |
2226 static_cast<const DataContentDescription*>(content); | 2258 static_cast<const DataContentDescription*>(content); |
2227 ASSERT(data != NULL); | 2259 ASSERT(data != NULL); |
2228 if (!data) { | 2260 if (!data) { |
2229 SafeSetError("Can't find data content in local description.", error_desc); | 2261 SafeSetError("Can't find data content in local description.", error_desc); |
2230 return false; | 2262 return false; |
2231 } | 2263 } |
2232 | 2264 |
2233 bool ret = false; | 2265 // CA_UPDATE is only used by the Harmony library to update send streams. |
2266 // TODO(pthatcher): Move this logic up into the Harmony library and | |
2267 // remove CA_UPDATE. | |
2268 if (action == CA_UPDATE && | |
2269 !UpdateLocalStreams_w(content->streams(), action, error_desc)) { | |
2270 SafeSetError("Failed to set local audio description send streams.", | |
2271 error_desc); | |
2272 return false; | |
2273 } | |
2274 | |
2234 if (!SetDataChannelTypeFromContent(data, error_desc)) { | 2275 if (!SetDataChannelTypeFromContent(data, error_desc)) { |
2235 return false; | 2276 return false; |
2236 } | 2277 } |
2237 | 2278 |
2238 if (data_channel_type_ == DCT_SCTP) { | 2279 if (data_channel_type_ == DCT_RTP) { |
2239 // SCTP data channels don't need the rest of the stuff. | 2280 if (!SetRtpTransportParameters_w(content, action, CS_LOCAL, error_desc)) { |
2240 ret = UpdateLocalStreams_w(data->streams(), action, error_desc); | 2281 return false; |
2241 if (ret) { | |
2242 set_local_content_direction(content->direction()); | |
2243 // As in SetRemoteContent_w, make sure we set the local SCTP port | |
2244 // number as specified in our DataContentDescription. | |
2245 if (!media_channel()->SetRecvCodecs(data->codecs())) { | |
2246 SafeSetError("Failed to set data receive codecs.", error_desc); | |
2247 ret = false; | |
2248 } | |
2249 } | 2282 } |
2250 } else { | 2283 |
2251 ret = SetBaseLocalContent_w(content, action, error_desc); | 2284 for (const DataCodec& codec : data->codecs()) { |
2252 if (action != CA_UPDATE || data->has_codecs()) { | 2285 bundle_filter()->AddPayloadType(codec.id); |
2253 if (!media_channel()->SetRecvCodecs(data->codecs())) { | |
2254 SafeSetError("Failed to set data receive codecs.", error_desc); | |
2255 ret = false; | |
2256 } | |
2257 } | 2286 } |
2258 } | 2287 } |
2259 | 2288 |
2260 // If everything worked, see if we can start receiving. | 2289 // FYI: We send the SCTP port number (not to be confused with the |
2261 if (ret) { | 2290 // underlying UDP port number) as a codec parameter. So even SCTP |
2262 std::vector<DataCodec>::const_iterator it = data->codecs().begin(); | 2291 // data channels need codecs. |
2263 for (; it != data->codecs().end(); ++it) { | 2292 DataRecvParameters recv_params; |
2264 bundle_filter()->AddPayloadType(it->id); | 2293 recv_params.codecs = data->codecs(); |
2265 } | 2294 if (!media_channel()->SetRecvParameters(recv_params)) { |
2266 ChangeState(); | 2295 SafeSetError("Failed to set remote data description recv parameters.", |
2267 } else { | 2296 error_desc); |
2268 LOG(LS_WARNING) << "Failed to set local data description"; | 2297 return false; |
2269 } | 2298 } |
2270 return ret; | 2299 |
2300 // TODO(pthatcher): Move local streams into DataSendParameters, and | |
2301 // only give it to the media channel once we have a remote | |
2302 // description too (without a remote description, we won't be able | |
2303 // to send them anyway). | |
2304 if (!UpdateLocalStreams_w(data->streams(), action, error_desc)) { | |
2305 SafeSetError("Failed to set local data description streams.", error_desc); | |
2306 return false; | |
2307 } | |
2308 | |
2309 set_local_content_direction(content->direction()); | |
2310 ChangeState(); | |
2311 return true; | |
2271 } | 2312 } |
2272 | 2313 |
2273 bool DataChannel::SetRemoteContent_w(const MediaContentDescription* content, | 2314 bool DataChannel::SetRemoteContent_w(const MediaContentDescription* content, |
2274 ContentAction action, | 2315 ContentAction action, |
2275 std::string* error_desc) { | 2316 std::string* error_desc) { |
2276 ASSERT(worker_thread() == rtc::Thread::Current()); | 2317 ASSERT(worker_thread() == rtc::Thread::Current()); |
2277 | 2318 |
2278 const DataContentDescription* data = | 2319 const DataContentDescription* data = |
2279 static_cast<const DataContentDescription*>(content); | 2320 static_cast<const DataContentDescription*>(content); |
2280 ASSERT(data != NULL); | 2321 ASSERT(data != NULL); |
2281 if (!data) { | 2322 if (!data) { |
2282 SafeSetError("Can't find data content in remote description.", error_desc); | 2323 SafeSetError("Can't find data content in remote description.", error_desc); |
2283 return false; | 2324 return false; |
2284 } | 2325 } |
2285 | 2326 |
2286 bool ret = true; | 2327 // CA_UPDATE is only used by the Harmony library to update send |
2328 // codecs and receive streams. | |
2329 // TODO(pthatcher): Move this logic up into the Harmony library and | |
2330 // remove CA_UPDATE. | |
2331 if (action == CA_UPDATE) { | |
2332 if (data->has_codecs() && !media_channel()->SetSendCodecs(data->codecs())) { | |
2333 SafeSetError("Failed to set remote data description send codecs.", | |
2334 error_desc); | |
2335 return false; | |
2336 } | |
2337 if (!UpdateRemoteStreams_w(content->streams(), action, error_desc)) { | |
2338 SafeSetError("Failed to set remote data description receive streams.", | |
2339 error_desc); | |
2340 return false; | |
2341 } | |
2342 return true; | |
2343 } | |
2344 | |
2345 // If the remote data doesn't have codecs and isn't an update, it | |
2346 // must be empty, so ignore it. | |
2347 if (!data->has_codecs()) { | |
2348 return true; | |
2349 } | |
2350 | |
2287 if (!SetDataChannelTypeFromContent(data, error_desc)) { | 2351 if (!SetDataChannelTypeFromContent(data, error_desc)) { |
2288 return false; | 2352 return false; |
2289 } | 2353 } |
2290 | 2354 |
2291 if (data_channel_type_ == DCT_SCTP) { | 2355 LOG(LS_INFO) << "Setting remote data description"; |
2292 LOG(LS_INFO) << "Setting SCTP remote data description"; | 2356 if (data_channel_type_ == DCT_RTP && |
2293 // SCTP data channels don't need the rest of the stuff. | 2357 !SetRtpTransportParameters_w(content, action, CS_REMOTE, error_desc)) { |
2294 ret = UpdateRemoteStreams_w(content->streams(), action, error_desc); | 2358 return false; |
2295 if (ret) { | |
2296 set_remote_content_direction(content->direction()); | |
2297 // We send the SCTP port number (not to be confused with the underlying | |
2298 // UDP port number) as a codec parameter. Make sure it gets there. | |
2299 if (!media_channel()->SetSendCodecs(data->codecs())) { | |
2300 SafeSetError("Failed to set data send codecs.", error_desc); | |
2301 ret = false; | |
2302 } | |
2303 } | |
2304 } else { | |
2305 // If the remote data doesn't have codecs and isn't an update, it | |
2306 // must be empty, so ignore it. | |
2307 if (action != CA_UPDATE && !data->has_codecs()) { | |
2308 return true; | |
2309 } | |
2310 LOG(LS_INFO) << "Setting remote data description"; | |
2311 | |
2312 // Set remote video codecs (what the other side wants to receive). | |
2313 if (action != CA_UPDATE || data->has_codecs()) { | |
2314 if (!media_channel()->SetSendCodecs(data->codecs())) { | |
2315 SafeSetError("Failed to set data send codecs.", error_desc); | |
2316 ret = false; | |
2317 } | |
2318 } | |
2319 | |
2320 if (ret) { | |
2321 ret &= SetBaseRemoteContent_w(content, action, error_desc); | |
2322 } | |
2323 | |
2324 if (action != CA_UPDATE) { | |
2325 int bandwidth_bps = data->bandwidth(); | |
2326 if (!media_channel()->SetMaxSendBandwidth(bandwidth_bps)) { | |
2327 std::ostringstream desc; | |
2328 desc << "Failed to set max send bandwidth for data content."; | |
2329 SafeSetError(desc.str(), error_desc); | |
2330 ret = false; | |
2331 } | |
2332 } | |
2333 } | 2359 } |
2334 | 2360 |
2335 // If everything worked, see if we can start sending. | 2361 DataSendParameters send_params; |
2336 if (ret) { | 2362 send_params.codecs = data->codecs(); |
2337 ChangeState(); | 2363 send_params.max_bandwidth_bps = data->bandwidth(); |
2338 } else { | 2364 if (!media_channel()->SetSendParameters(send_params)) { |
2339 LOG(LS_WARNING) << "Failed to set remote data description"; | 2365 SafeSetError("Failed to set remote data description send parameters.", |
2366 error_desc); | |
2367 return false; | |
2340 } | 2368 } |
2341 return ret; | 2369 |
2370 // TODO(pthatcher): Move remote streams into DataRecvParameters, | |
2371 // and only give it to the media channel once we have a local | |
2372 // description too (without a local description, we won't be able to | |
2373 // recv them anyway). | |
2374 if (!UpdateRemoteStreams_w(data->streams(), action, error_desc)) { | |
2375 SafeSetError("Failed to set remote data description streams.", | |
2376 error_desc); | |
2377 return false; | |
2378 } | |
2379 | |
2380 set_remote_content_direction(content->direction()); | |
2381 ChangeState(); | |
2382 return true; | |
2342 } | 2383 } |
2343 | 2384 |
2344 void DataChannel::ChangeState() { | 2385 void DataChannel::ChangeState() { |
2345 // Render incoming data if we're the active call, and we have the local | 2386 // Render incoming data if we're the active call, and we have the local |
2346 // content. We receive data on the default channel and multiplexed streams. | 2387 // content. We receive data on the default channel and multiplexed streams. |
2347 bool recv = IsReadyToReceive(); | 2388 bool recv = IsReadyToReceive(); |
2348 if (!media_channel()->SetReceive(recv)) { | 2389 if (!media_channel()->SetReceive(recv)) { |
2349 LOG(LS_ERROR) << "Failed to SetReceive on data channel"; | 2390 LOG(LS_ERROR) << "Failed to SetReceive on data channel"; |
2350 } | 2391 } |
2351 | 2392 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2479 return (data_channel_type_ == DCT_RTP); | 2520 return (data_channel_type_ == DCT_RTP); |
2480 } | 2521 } |
2481 | 2522 |
2482 void DataChannel::OnStreamClosedRemotely(uint32 sid) { | 2523 void DataChannel::OnStreamClosedRemotely(uint32 sid) { |
2483 rtc::TypedMessageData<uint32>* message = | 2524 rtc::TypedMessageData<uint32>* message = |
2484 new rtc::TypedMessageData<uint32>(sid); | 2525 new rtc::TypedMessageData<uint32>(sid); |
2485 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); | 2526 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); |
2486 } | 2527 } |
2487 | 2528 |
2488 } // namespace cricket | 2529 } // namespace cricket |
OLD | NEW |