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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
143 return direction == MD_SENDRECV || direction == MD_SENDONLY; | 143 return direction == MD_SENDRECV || direction == MD_SENDONLY; |
144 } | 144 } |
145 | 145 |
146 static const MediaContentDescription* GetContentDescription( | 146 static const MediaContentDescription* GetContentDescription( |
147 const ContentInfo* cinfo) { | 147 const ContentInfo* cinfo) { |
148 if (cinfo == NULL) | 148 if (cinfo == NULL) |
149 return NULL; | 149 return NULL; |
150 return static_cast<const MediaContentDescription*>(cinfo->description); | 150 return static_cast<const MediaContentDescription*>(cinfo->description); |
151 } | 151 } |
152 | 152 |
153 template <class Codec> | |
154 void RtpParametersFromMediaDescription( | |
155 const MediaContentDescriptionImpl<Codec>* desc, | |
156 RtpParameters<Codec>* params) { | |
157 // TODO(pthatcher): Remove this once we're sure no one will give us | |
158 // a description without codecs (currently a CA_UPDATE with just | |
159 // streams can). | |
160 if (desc->has_codecs()) { | |
Taylor Brandstetter
2015/07/18 00:16:31
Are you sure only a CA_UPDATE will give a descript
pthatcher1
2015/07/31 10:59:20
If anything other than a CA_UPDATE has an empty li
| |
161 params->codecs = desc->codecs(); | |
162 } | |
163 // TODO(pthatcher): See if we really need | |
164 // rtp_header_extensions_set() and remove it if we don't. | |
165 if (desc->rtp_header_extensions_set()) { | |
166 params->extensions = desc->rtp_header_extensions(); | |
167 } | |
168 } | |
169 | |
170 template <class Codec, class Options> | |
171 void RtpSendParametersFromMediaDescription( | |
172 const MediaContentDescriptionImpl<Codec>* desc, | |
173 RtpSendParameters<Codec, Options>* send_params) { | |
174 RtpParametersFromMediaDescription(desc, send_params); | |
175 send_params->max_bandwidth_bps = desc->bandwidth(); | |
176 } | |
177 | |
153 BaseChannel::BaseChannel(rtc::Thread* thread, | 178 BaseChannel::BaseChannel(rtc::Thread* thread, |
154 MediaEngineInterface* media_engine, | 179 MediaEngineInterface* media_engine, |
155 MediaChannel* media_channel, BaseSession* session, | 180 MediaChannel* media_channel, BaseSession* session, |
156 const std::string& content_name, bool rtcp) | 181 const std::string& content_name, bool rtcp) |
157 : worker_thread_(thread), | 182 : worker_thread_(thread), |
158 media_engine_(media_engine), | 183 media_engine_(media_engine), |
159 session_(session), | 184 session_(session), |
160 media_channel_(media_channel), | 185 media_channel_(media_channel), |
161 content_name_(content_name), | 186 content_name_(content_name), |
162 rtcp_(rtcp), | 187 rtcp_(rtcp), |
(...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
892 if (!writable_) | 917 if (!writable_) |
893 return; | 918 return; |
894 | 919 |
895 LOG(LS_INFO) << "Channel socket not writable (" | 920 LOG(LS_INFO) << "Channel socket not writable (" |
896 << transport_channel_->content_name() << ", " | 921 << transport_channel_->content_name() << ", " |
897 << transport_channel_->component() << ")"; | 922 << transport_channel_->component() << ")"; |
898 writable_ = false; | 923 writable_ = false; |
899 ChangeState(); | 924 ChangeState(); |
900 } | 925 } |
901 | 926 |
927 bool BaseChannel::SetRtpTransportParameters_w( | |
928 const MediaContentDescription* content, | |
929 ContentAction action, | |
930 ContentSource src, | |
931 std::string* error_desc) { | |
932 if (action == CA_UPDATE) { | |
933 // These parameters never get changed by a CA_UDPATE. | |
934 return true; | |
935 } | |
936 | |
937 // Cache secure_required_ for belt and suspenders check on SendPacket | |
938 set_secure_required(content->crypto_required() != CT_NONE); | |
Taylor Brandstetter
2015/07/18 00:16:31
Should set_secure_required only be called here if
pthatcher1
2015/07/31 10:59:20
Good catch. I've fixed it.
| |
939 if (!SetSrtp_w(content->cryptos(), action, src, error_desc)) { | |
940 return false; | |
941 } | |
942 | |
943 if (!SetRtcpMux_w(content->rtcp_mux(), action, src, error_desc)) { | |
944 return false; | |
945 } | |
946 | |
947 return true; | |
948 } | |
949 | |
902 // |dtls| will be set to true if DTLS is active for transport channel and | 950 // |dtls| will be set to true if DTLS is active for transport channel and |
903 // crypto is empty. | 951 // crypto is empty. |
904 bool BaseChannel::CheckSrtpConfig(const std::vector<CryptoParams>& cryptos, | 952 bool BaseChannel::CheckSrtpConfig(const std::vector<CryptoParams>& cryptos, |
905 bool* dtls, | 953 bool* dtls, |
906 std::string* error_desc) { | 954 std::string* error_desc) { |
907 *dtls = transport_channel_->IsDtlsActive(); | 955 *dtls = transport_channel_->IsDtlsActive(); |
908 if (*dtls && !cryptos.empty()) { | 956 if (*dtls && !cryptos.empty()) { |
909 SafeSetError("Cryptos must be empty when DTLS is active.", | 957 SafeSetError("Cryptos must be empty when DTLS is active.", |
910 error_desc); | 958 error_desc); |
911 return false; | 959 return false; |
912 } | 960 } |
913 return true; | 961 return true; |
914 } | 962 } |
915 | 963 |
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, | 964 bool BaseChannel::SetSrtp_w(const std::vector<CryptoParams>& cryptos, |
953 ContentAction action, | 965 ContentAction action, |
954 ContentSource src, | 966 ContentSource src, |
955 std::string* error_desc) { | 967 std::string* error_desc) { |
956 if (action == CA_UPDATE) { | 968 if (action == CA_UPDATE) { |
957 // no crypto params. | 969 // no crypto params. |
958 return true; | 970 return true; |
959 } | 971 } |
960 bool ret = false; | 972 bool ret = false; |
961 bool dtls = false; | 973 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(); | 1215 desc << "Failed to add remote stream ssrc: " << it->first_ssrc(); |
1204 SafeSetError(desc.str(), error_desc); | 1216 SafeSetError(desc.str(), error_desc); |
1205 ret = false; | 1217 ret = false; |
1206 } | 1218 } |
1207 } | 1219 } |
1208 } | 1220 } |
1209 remote_streams_ = streams; | 1221 remote_streams_ = streams; |
1210 return ret; | 1222 return ret; |
1211 } | 1223 } |
1212 | 1224 |
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( | 1225 void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension( |
1257 const std::vector<RtpHeaderExtension>& extensions) { | 1226 const std::vector<RtpHeaderExtension>& extensions) { |
1258 const RtpHeaderExtension* send_time_extension = | 1227 const RtpHeaderExtension* send_time_extension = |
1259 FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); | 1228 FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); |
1260 rtp_abs_sendtime_extn_id_ = | 1229 rtp_abs_sendtime_extn_id_ = |
1261 send_time_extension ? send_time_extension->id : -1; | 1230 send_time_extension ? send_time_extension->id : -1; |
1262 } | 1231 } |
1263 | 1232 |
1264 void BaseChannel::OnMessage(rtc::Message *pmsg) { | 1233 void BaseChannel::OnMessage(rtc::Message *pmsg) { |
1265 switch (pmsg->message_id) { | 1234 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"; | 1464 LOG(LS_INFO) << "Setting local voice description"; |
1496 | 1465 |
1497 const AudioContentDescription* audio = | 1466 const AudioContentDescription* audio = |
1498 static_cast<const AudioContentDescription*>(content); | 1467 static_cast<const AudioContentDescription*>(content); |
1499 ASSERT(audio != NULL); | 1468 ASSERT(audio != NULL); |
1500 if (!audio) { | 1469 if (!audio) { |
1501 SafeSetError("Can't find audio content in local description.", error_desc); | 1470 SafeSetError("Can't find audio content in local description.", error_desc); |
1502 return false; | 1471 return false; |
1503 } | 1472 } |
1504 | 1473 |
1505 bool ret = SetBaseLocalContent_w(content, action, error_desc); | 1474 if (!SetRtpTransportParameters_w(content, action, CS_LOCAL, error_desc)) { |
Taylor Brandstetter
2015/07/18 00:16:31
If SetRtpTransportParameters_w fails, this method
pthatcher1
2015/07/31 10:59:20
SetRtpTransportParameters_w will set the error lik
| |
1506 // Set local audio codecs (what we want to receive). | 1475 return false; |
1507 // TODO(whyuan): Change action != CA_UPDATE to !audio->partial() when partial | |
1508 // is set properly. | |
1509 if (action != CA_UPDATE || audio->has_codecs()) { | |
1510 if (!media_channel()->SetRecvCodecs(audio->codecs())) { | |
1511 SafeSetError("Failed to set audio receive codecs.", error_desc); | |
1512 ret = false; | |
1513 } | |
1514 } | 1476 } |
1515 | 1477 |
1516 // If everything worked, see if we can start receiving. | 1478 AudioRecvParameters recv_params = last_recv_params_; |
1517 if (ret) { | 1479 RtpParametersFromMediaDescription(audio, &recv_params); |
1518 std::vector<AudioCodec>::const_iterator it = audio->codecs().begin(); | 1480 if (!media_channel()->SetRecvParameters(recv_params)) { |
1519 for (; it != audio->codecs().end(); ++it) { | 1481 SafeSetError("Failed to set local video description recv parameters.", |
1520 bundle_filter()->AddPayloadType(it->id); | 1482 error_desc); |
1521 } | 1483 return false; |
1522 ChangeState(); | |
1523 } else { | |
1524 LOG(LS_WARNING) << "Failed to set local voice description"; | |
1525 } | 1484 } |
1526 return ret; | 1485 for (const AudioCodec& codec : audio->codecs()) { |
1486 bundle_filter()->AddPayloadType(codec.id); | |
1487 } | |
1488 last_recv_params_ = recv_params; | |
1489 | |
1490 // TODO(pthatcher): Move local streams into AudioSendParameters, and | |
1491 // only give it to the media channel once we have a remote | |
1492 // description too (without a remote description, we won't be able | |
1493 // to send them anyway). | |
1494 if (!UpdateLocalStreams_w(audio->streams(), action, error_desc)) { | |
1495 SafeSetError("Failed to set local audio description streams.", error_desc); | |
1496 return false; | |
1497 } | |
1498 | |
1499 set_local_content_direction(content->direction()); | |
1500 ChangeState(); | |
1501 return true; | |
1527 } | 1502 } |
1528 | 1503 |
1529 bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content, | 1504 bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content, |
1530 ContentAction action, | 1505 ContentAction action, |
1531 std::string* error_desc) { | 1506 std::string* error_desc) { |
1532 ASSERT(worker_thread() == rtc::Thread::Current()); | 1507 ASSERT(worker_thread() == rtc::Thread::Current()); |
1533 LOG(LS_INFO) << "Setting remote voice description"; | 1508 LOG(LS_INFO) << "Setting remote voice description"; |
1534 | 1509 |
1535 const AudioContentDescription* audio = | 1510 const AudioContentDescription* audio = |
1536 static_cast<const AudioContentDescription*>(content); | 1511 static_cast<const AudioContentDescription*>(content); |
1537 ASSERT(audio != NULL); | 1512 ASSERT(audio != NULL); |
1538 if (!audio) { | 1513 if (!audio) { |
1539 SafeSetError("Can't find audio content in remote description.", error_desc); | 1514 SafeSetError("Can't find audio content in remote description.", error_desc); |
1540 return false; | 1515 return false; |
1541 } | 1516 } |
1542 | 1517 |
1543 bool ret = true; | 1518 if (!SetRtpTransportParameters_w(content, action, CS_REMOTE, error_desc)) { |
1544 // Set remote video codecs (what the other side wants to receive). | 1519 return false; |
1545 if (action != CA_UPDATE || audio->has_codecs()) { | |
1546 if (!media_channel()->SetSendCodecs(audio->codecs())) { | |
1547 SafeSetError("Failed to set audio send codecs.", error_desc); | |
1548 ret = false; | |
1549 } | |
1550 } | 1520 } |
1551 | 1521 |
1552 ret &= SetBaseRemoteContent_w(content, action, error_desc); | 1522 AudioSendParameters send_params = last_send_params_; |
1523 RtpSendParametersFromMediaDescription(audio, &send_params); | |
1524 if (audio->conference_mode()) { | |
1525 send_params.options.conference_mode.Set(true); | |
1526 } | |
1527 if (audio->agc_minus_10db()) { | |
1528 send_params.options.adjust_agc_delta.Set(kAgcMinus10db); | |
1529 } | |
1530 if (!media_channel()->SetSendParameters(send_params)) { | |
1531 SafeSetError("Failed to set remote audio description send parameters.", | |
1532 error_desc); | |
1533 return false; | |
1534 } | |
1535 last_send_params_ = send_params; | |
1553 | 1536 |
1554 if (action != CA_UPDATE) { | 1537 // TODO(pthatcher): Move remote streams into AudioRecvParameters, |
1555 // Tweak our audio processing settings, if needed. | 1538 // and only give it to the media channel once we have a local |
1556 AudioOptions audio_options; | 1539 // description too (without a local description, we won't be able to |
1557 if (!media_channel()->GetOptions(&audio_options)) { | 1540 // recv them anyway). |
1558 LOG(LS_WARNING) << "Can not set audio options from on remote content."; | 1541 if (!UpdateRemoteStreams_w(audio->streams(), action, error_desc)) { |
1559 } else { | 1542 LOG(LS_WARNING) << "Failed to set remote audio description receive streams"; |
Taylor Brandstetter
2015/07/18 00:16:31
I notice that SafeSetError is used if UpdateLocalS
pthatcher1
2015/07/31 10:59:20
Good catch.
Fixed.
| |
1560 if (audio->conference_mode()) { | 1543 return false; |
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 } | 1544 } |
1572 | 1545 |
1573 // If everything worked, see if we can start sending. | 1546 set_remote_content_direction(content->direction()); |
1574 if (ret) { | 1547 ChangeState(); |
1575 ChangeState(); | 1548 return true; |
1576 } else { | |
1577 LOG(LS_WARNING) << "Failed to set remote voice description"; | |
1578 } | |
1579 return ret; | |
1580 } | 1549 } |
1581 | 1550 |
1582 bool VoiceChannel::SetRingbackTone_w(const void* buf, int len) { | 1551 bool VoiceChannel::SetRingbackTone_w(const void* buf, int len) { |
1583 ASSERT(worker_thread() == rtc::Thread::Current()); | 1552 ASSERT(worker_thread() == rtc::Thread::Current()); |
1584 return media_channel()->SetRingbackTone(static_cast<const char*>(buf), len); | 1553 return media_channel()->SetRingbackTone(static_cast<const char*>(buf), len); |
1585 } | 1554 } |
1586 | 1555 |
1587 bool VoiceChannel::PlayRingbackTone_w(uint32 ssrc, bool play, bool loop) { | 1556 bool VoiceChannel::PlayRingbackTone_w(uint32 ssrc, bool play, bool loop) { |
1588 ASSERT(worker_thread() == rtc::Thread::Current()); | 1557 ASSERT(worker_thread() == rtc::Thread::Current()); |
1589 if (play) { | 1558 if (play) { |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1839 LOG(LS_INFO) << "Setting local video description"; | 1808 LOG(LS_INFO) << "Setting local video description"; |
1840 | 1809 |
1841 const VideoContentDescription* video = | 1810 const VideoContentDescription* video = |
1842 static_cast<const VideoContentDescription*>(content); | 1811 static_cast<const VideoContentDescription*>(content); |
1843 ASSERT(video != NULL); | 1812 ASSERT(video != NULL); |
1844 if (!video) { | 1813 if (!video) { |
1845 SafeSetError("Can't find video content in local description.", error_desc); | 1814 SafeSetError("Can't find video content in local description.", error_desc); |
1846 return false; | 1815 return false; |
1847 } | 1816 } |
1848 | 1817 |
1849 bool ret = SetBaseLocalContent_w(content, action, error_desc); | 1818 if (!SetRtpTransportParameters_w(content, action, CS_LOCAL, error_desc)) { |
1850 // Set local video codecs (what we want to receive). | 1819 return false; |
1851 if (action != CA_UPDATE || video->has_codecs()) { | |
1852 if (!media_channel()->SetRecvCodecs(video->codecs())) { | |
1853 SafeSetError("Failed to set video receive codecs.", error_desc); | |
1854 ret = false; | |
1855 } | |
1856 } | 1820 } |
1857 | 1821 |
1858 if (action != CA_UPDATE) { | 1822 VideoRecvParameters recv_params = last_recv_params_; |
1859 VideoOptions video_options; | 1823 RtpParametersFromMediaDescription(video, &recv_params); |
1860 media_channel()->GetOptions(&video_options); | 1824 if (!media_channel()->SetRecvParameters(recv_params)) { |
1861 if (!media_channel()->SetOptions(video_options)) { | 1825 SafeSetError("Failed to set local video description recv parameters.", |
1862 // Log an error on failure, but don't abort the call. | 1826 error_desc); |
1863 LOG(LS_ERROR) << "Failed to set video channel options"; | 1827 return false; |
1864 } | 1828 } |
1829 for (const VideoCodec& codec : video->codecs()) { | |
1830 bundle_filter()->AddPayloadType(codec.id); | |
1831 } | |
1832 last_recv_params_ = recv_params; | |
1833 | |
1834 // TODO(pthatcher): Move local streams into VideoSendParameters, and | |
1835 // only give it to the media channel once we have a remote | |
1836 // description too (without a remote description, we won't be able | |
1837 // to send them anyway). | |
1838 if (!UpdateLocalStreams_w(video->streams(), action, error_desc)) { | |
1839 SafeSetError("Failed to set local video description streams.", error_desc); | |
1840 return false; | |
1865 } | 1841 } |
1866 | 1842 |
1867 // If everything worked, see if we can start receiving. | 1843 set_local_content_direction(content->direction()); |
1868 if (ret) { | 1844 ChangeState(); |
1869 std::vector<VideoCodec>::const_iterator it = video->codecs().begin(); | 1845 return true; |
1870 for (; it != video->codecs().end(); ++it) { | |
1871 bundle_filter()->AddPayloadType(it->id); | |
1872 } | |
1873 ChangeState(); | |
1874 } else { | |
1875 LOG(LS_WARNING) << "Failed to set local video description"; | |
1876 } | |
1877 return ret; | |
1878 } | 1846 } |
1879 | 1847 |
1880 bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content, | 1848 bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content, |
1881 ContentAction action, | 1849 ContentAction action, |
1882 std::string* error_desc) { | 1850 std::string* error_desc) { |
1883 ASSERT(worker_thread() == rtc::Thread::Current()); | 1851 ASSERT(worker_thread() == rtc::Thread::Current()); |
1884 LOG(LS_INFO) << "Setting remote video description"; | 1852 LOG(LS_INFO) << "Setting remote video description"; |
1885 | 1853 |
1886 const VideoContentDescription* video = | 1854 const VideoContentDescription* video = |
1887 static_cast<const VideoContentDescription*>(content); | 1855 static_cast<const VideoContentDescription*>(content); |
1888 ASSERT(video != NULL); | 1856 ASSERT(video != NULL); |
1889 if (!video) { | 1857 if (!video) { |
1890 SafeSetError("Can't find video content in remote description.", error_desc); | 1858 SafeSetError("Can't find video content in remote description.", error_desc); |
1891 return false; | 1859 return false; |
1892 } | 1860 } |
1893 | 1861 |
1894 bool ret = true; | 1862 |
1895 // Set remote video codecs (what the other side wants to receive). | 1863 if (!SetRtpTransportParameters_w(content, action, CS_REMOTE, error_desc)) { |
1896 if (action != CA_UPDATE || video->has_codecs()) { | 1864 return false; |
1897 if (!media_channel()->SetSendCodecs(video->codecs())) { | |
1898 SafeSetError("Failed to set video send codecs.", error_desc); | |
1899 ret = false; | |
1900 } | |
1901 } | 1865 } |
1902 | 1866 |
1903 ret &= SetBaseRemoteContent_w(content, action, error_desc); | 1867 VideoSendParameters send_params = last_send_params_; |
1868 RtpSendParametersFromMediaDescription(video, &send_params); | |
1869 if (video->conference_mode()) { | |
1870 send_params.options.conference_mode.Set(true); | |
1871 } | |
1872 if (!media_channel()->SetSendParameters(send_params)) { | |
1873 SafeSetError("Failed to set remote video description send parameters.", | |
1874 error_desc); | |
1875 return false; | |
1876 } | |
1877 last_send_params_ = send_params; | |
1904 | 1878 |
1905 if (action != CA_UPDATE) { | 1879 // TODO(pthatcher): Move remote streams into VideoRecvParameters, |
1906 // Tweak our video processing settings, if needed. | 1880 // and only give it to the media channel once we have a local |
1907 VideoOptions video_options; | 1881 // description too (without a local description, we won't be able to |
1908 media_channel()->GetOptions(&video_options); | 1882 // recv them anyway). |
1909 if (video->conference_mode()) { | 1883 if (!UpdateRemoteStreams_w(video->streams(), action, error_desc)) { |
1910 video_options.conference_mode.Set(true); | 1884 LOG(LS_WARNING) << "Failed to set remote video description receive streams"; |
1911 } | 1885 return false; |
1912 | |
1913 if (!media_channel()->SetOptions(video_options)) { | |
1914 // Log an error on failure, but don't abort the call. | |
1915 LOG(LS_ERROR) << "Failed to set video channel options"; | |
1916 } | |
1917 } | 1886 } |
1918 | 1887 |
1919 // If everything worked, see if we can start sending. | 1888 if (video->rtp_header_extensions_set()) { |
1920 if (ret) { | 1889 MaybeCacheRtpAbsSendTimeHeaderExtension(video->rtp_header_extensions()); |
1921 ChangeState(); | |
1922 } else { | |
1923 LOG(LS_WARNING) << "Failed to set remote video description"; | |
1924 } | 1890 } |
1925 return ret; | 1891 |
1892 set_remote_content_direction(content->direction()); | |
1893 ChangeState(); | |
1894 return true; | |
1926 } | 1895 } |
1927 | 1896 |
1928 bool VideoChannel::ApplyViewRequest_w(const ViewRequest& request) { | 1897 bool VideoChannel::ApplyViewRequest_w(const ViewRequest& request) { |
1929 bool ret = true; | 1898 bool ret = true; |
1930 // Set the send format for each of the local streams. If the view request | 1899 // Set the send format for each of the local streams. If the view request |
1931 // does not contain a local stream, set its send format to 0x0, which will | 1900 // does not contain a local stream, set its send format to 0x0, which will |
1932 // drop all frames. | 1901 // drop all frames. |
1933 for (std::vector<StreamParams>::const_iterator it = local_streams().begin(); | 1902 for (std::vector<StreamParams>::const_iterator it = local_streams().begin(); |
1934 it != local_streams().end(); ++it) { | 1903 it != local_streams().end(); ++it) { |
1935 VideoFormat format(0, 0, 0, cricket::FOURCC_I420); | 1904 VideoFormat format(0, 0, 0, cricket::FOURCC_I420); |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2220 LOG(LS_INFO) << "Setting local data description"; | 2189 LOG(LS_INFO) << "Setting local data description"; |
2221 | 2190 |
2222 const DataContentDescription* data = | 2191 const DataContentDescription* data = |
2223 static_cast<const DataContentDescription*>(content); | 2192 static_cast<const DataContentDescription*>(content); |
2224 ASSERT(data != NULL); | 2193 ASSERT(data != NULL); |
2225 if (!data) { | 2194 if (!data) { |
2226 SafeSetError("Can't find data content in local description.", error_desc); | 2195 SafeSetError("Can't find data content in local description.", error_desc); |
2227 return false; | 2196 return false; |
2228 } | 2197 } |
2229 | 2198 |
2230 bool ret = false; | |
2231 if (!SetDataChannelTypeFromContent(data, error_desc)) { | 2199 if (!SetDataChannelTypeFromContent(data, error_desc)) { |
2232 return false; | 2200 return false; |
2233 } | 2201 } |
2234 | 2202 |
2235 if (data_channel_type_ == DCT_SCTP) { | 2203 if (data_channel_type_ == DCT_RTP) { |
2236 // SCTP data channels don't need the rest of the stuff. | 2204 if (!SetRtpTransportParameters_w(content, action, CS_LOCAL, error_desc)) { |
2237 ret = UpdateLocalStreams_w(data->streams(), action, error_desc); | 2205 return false; |
2238 if (ret) { | |
2239 set_local_content_direction(content->direction()); | |
2240 // As in SetRemoteContent_w, make sure we set the local SCTP port | |
2241 // number as specified in our DataContentDescription. | |
2242 if (!media_channel()->SetRecvCodecs(data->codecs())) { | |
2243 SafeSetError("Failed to set data receive codecs.", error_desc); | |
2244 ret = false; | |
2245 } | |
2246 } | |
2247 } else { | |
2248 ret = SetBaseLocalContent_w(content, action, error_desc); | |
2249 if (action != CA_UPDATE || data->has_codecs()) { | |
2250 if (!media_channel()->SetRecvCodecs(data->codecs())) { | |
2251 SafeSetError("Failed to set data receive codecs.", error_desc); | |
2252 ret = false; | |
2253 } | |
2254 } | 2206 } |
2255 } | 2207 } |
2256 | 2208 |
2257 // If everything worked, see if we can start receiving. | 2209 // FYI: We send the SCTP port number (not to be confused with the |
2258 if (ret) { | 2210 // underlying UDP port number) as a codec parameter. So even SCTP |
2259 std::vector<DataCodec>::const_iterator it = data->codecs().begin(); | 2211 // data channels need codecs. |
2260 for (; it != data->codecs().end(); ++it) { | 2212 DataRecvParameters recv_params = last_recv_params_; |
2261 bundle_filter()->AddPayloadType(it->id); | 2213 RtpParametersFromMediaDescription(data, &recv_params); |
2214 if (!media_channel()->SetRecvParameters(recv_params)) { | |
2215 SafeSetError("Failed to set remote data description recv parameters.", | |
2216 error_desc); | |
2217 return false; | |
2218 } | |
2219 if (data_channel_type_ == DCT_RTP) { | |
2220 for (const DataCodec& codec : data->codecs()) { | |
2221 bundle_filter()->AddPayloadType(codec.id); | |
2262 } | 2222 } |
2263 ChangeState(); | |
2264 } else { | |
2265 LOG(LS_WARNING) << "Failed to set local data description"; | |
2266 } | 2223 } |
2267 return ret; | 2224 last_recv_params_ = recv_params; |
2225 | |
2226 // TODO(pthatcher): Move local streams into DataSendParameters, and | |
2227 // only give it to the media channel once we have a remote | |
2228 // description too (without a remote description, we won't be able | |
2229 // to send them anyway). | |
2230 if (!UpdateLocalStreams_w(data->streams(), action, error_desc)) { | |
2231 SafeSetError("Failed to set local data description streams.", error_desc); | |
2232 return false; | |
2233 } | |
2234 | |
2235 set_local_content_direction(content->direction()); | |
2236 ChangeState(); | |
2237 return true; | |
2268 } | 2238 } |
2269 | 2239 |
2270 bool DataChannel::SetRemoteContent_w(const MediaContentDescription* content, | 2240 bool DataChannel::SetRemoteContent_w(const MediaContentDescription* content, |
2271 ContentAction action, | 2241 ContentAction action, |
2272 std::string* error_desc) { | 2242 std::string* error_desc) { |
2273 ASSERT(worker_thread() == rtc::Thread::Current()); | 2243 ASSERT(worker_thread() == rtc::Thread::Current()); |
2274 | 2244 |
2275 const DataContentDescription* data = | 2245 const DataContentDescription* data = |
2276 static_cast<const DataContentDescription*>(content); | 2246 static_cast<const DataContentDescription*>(content); |
2277 ASSERT(data != NULL); | 2247 ASSERT(data != NULL); |
2278 if (!data) { | 2248 if (!data) { |
2279 SafeSetError("Can't find data content in remote description.", error_desc); | 2249 SafeSetError("Can't find data content in remote description.", error_desc); |
2280 return false; | 2250 return false; |
2281 } | 2251 } |
2282 | 2252 |
2283 bool ret = true; | 2253 // If the remote data doesn't have codecs and isn't an update, it |
2254 // must be empty, so ignore it. | |
2255 if (!data->has_codecs() && action != CA_UPDATE) { | |
2256 return true; | |
2257 } | |
2258 | |
2284 if (!SetDataChannelTypeFromContent(data, error_desc)) { | 2259 if (!SetDataChannelTypeFromContent(data, error_desc)) { |
2285 return false; | 2260 return false; |
2286 } | 2261 } |
2287 | 2262 |
2288 if (data_channel_type_ == DCT_SCTP) { | 2263 LOG(LS_INFO) << "Setting remote data description"; |
2289 LOG(LS_INFO) << "Setting SCTP remote data description"; | 2264 if (data_channel_type_ == DCT_RTP && |
2290 // SCTP data channels don't need the rest of the stuff. | 2265 !SetRtpTransportParameters_w(content, action, CS_REMOTE, error_desc)) { |
2291 ret = UpdateRemoteStreams_w(content->streams(), action, error_desc); | 2266 return false; |
2292 if (ret) { | |
2293 set_remote_content_direction(content->direction()); | |
2294 // We send the SCTP port number (not to be confused with the underlying | |
2295 // UDP port number) as a codec parameter. Make sure it gets there. | |
2296 if (!media_channel()->SetSendCodecs(data->codecs())) { | |
2297 SafeSetError("Failed to set data send codecs.", error_desc); | |
2298 ret = false; | |
2299 } | |
2300 } | |
2301 } else { | |
2302 // If the remote data doesn't have codecs and isn't an update, it | |
2303 // must be empty, so ignore it. | |
2304 if (action != CA_UPDATE && !data->has_codecs()) { | |
2305 return true; | |
2306 } | |
2307 LOG(LS_INFO) << "Setting remote data description"; | |
2308 | |
2309 // Set remote video codecs (what the other side wants to receive). | |
2310 if (action != CA_UPDATE || data->has_codecs()) { | |
2311 if (!media_channel()->SetSendCodecs(data->codecs())) { | |
2312 SafeSetError("Failed to set data send codecs.", error_desc); | |
2313 ret = false; | |
2314 } | |
2315 } | |
2316 | |
2317 if (ret) { | |
2318 ret &= SetBaseRemoteContent_w(content, action, error_desc); | |
2319 } | |
2320 | |
2321 if (action != CA_UPDATE) { | |
2322 int bandwidth_bps = data->bandwidth(); | |
2323 if (!media_channel()->SetMaxSendBandwidth(bandwidth_bps)) { | |
2324 std::ostringstream desc; | |
2325 desc << "Failed to set max send bandwidth for data content."; | |
2326 SafeSetError(desc.str(), error_desc); | |
2327 ret = false; | |
2328 } | |
2329 } | |
2330 } | 2267 } |
2331 | 2268 |
2332 // If everything worked, see if we can start sending. | 2269 |
2333 if (ret) { | 2270 DataSendParameters send_params = last_send_params_; |
2334 ChangeState(); | 2271 RtpSendParametersFromMediaDescription<DataCodec>(data, &send_params); |
2335 } else { | 2272 if (!media_channel()->SetSendParameters(send_params)) { |
2336 LOG(LS_WARNING) << "Failed to set remote data description"; | 2273 SafeSetError("Failed to set remote data description send parameters.", |
2274 error_desc); | |
2275 return false; | |
2337 } | 2276 } |
2338 return ret; | 2277 last_send_params_ = send_params; |
2278 | |
2279 // TODO(pthatcher): Move remote streams into DataRecvParameters, | |
2280 // and only give it to the media channel once we have a local | |
2281 // description too (without a local description, we won't be able to | |
2282 // recv them anyway). | |
2283 if (!UpdateRemoteStreams_w(data->streams(), action, error_desc)) { | |
2284 SafeSetError("Failed to set remote data description streams.", | |
2285 error_desc); | |
2286 return false; | |
2287 } | |
2288 | |
2289 set_remote_content_direction(content->direction()); | |
2290 ChangeState(); | |
2291 return true; | |
2339 } | 2292 } |
2340 | 2293 |
2341 void DataChannel::ChangeState() { | 2294 void DataChannel::ChangeState() { |
2342 // Render incoming data if we're the active call, and we have the local | 2295 // Render incoming data if we're the active call, and we have the local |
2343 // content. We receive data on the default channel and multiplexed streams. | 2296 // content. We receive data on the default channel and multiplexed streams. |
2344 bool recv = IsReadyToReceive(); | 2297 bool recv = IsReadyToReceive(); |
2345 if (!media_channel()->SetReceive(recv)) { | 2298 if (!media_channel()->SetReceive(recv)) { |
2346 LOG(LS_ERROR) << "Failed to SetReceive on data channel"; | 2299 LOG(LS_ERROR) << "Failed to SetReceive on data channel"; |
2347 } | 2300 } |
2348 | 2301 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2476 return (data_channel_type_ == DCT_RTP); | 2429 return (data_channel_type_ == DCT_RTP); |
2477 } | 2430 } |
2478 | 2431 |
2479 void DataChannel::OnStreamClosedRemotely(uint32 sid) { | 2432 void DataChannel::OnStreamClosedRemotely(uint32 sid) { |
2480 rtc::TypedMessageData<uint32>* message = | 2433 rtc::TypedMessageData<uint32>* message = |
2481 new rtc::TypedMessageData<uint32>(sid); | 2434 new rtc::TypedMessageData<uint32>(sid); |
2482 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); | 2435 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); |
2483 } | 2436 } |
2484 | 2437 |
2485 } // namespace cricket | 2438 } // namespace cricket |
OLD | NEW |