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