Chromium Code Reviews| 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 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 if (src == CS_LOCAL) { | |
| 939 set_secure_required(content->crypto_required() != CT_NONE); | |
| 940 } | |
| 941 | |
| 942 if (!SetSrtp_w(content->cryptos(), action, src, error_desc)) { | |
| 943 return false; | |
| 944 } | |
| 945 | |
| 946 if (!SetRtcpMux_w(content->rtcp_mux(), action, src, error_desc)) { | |
| 947 return false; | |
| 948 } | |
| 949 | |
| 950 return true; | |
| 951 } | |
| 952 | |
| 902 // |dtls| will be set to true if DTLS is active for transport channel and | 953 // |dtls| will be set to true if DTLS is active for transport channel and |
| 903 // crypto is empty. | 954 // crypto is empty. |
| 904 bool BaseChannel::CheckSrtpConfig(const std::vector<CryptoParams>& cryptos, | 955 bool BaseChannel::CheckSrtpConfig(const std::vector<CryptoParams>& cryptos, |
| 905 bool* dtls, | 956 bool* dtls, |
| 906 std::string* error_desc) { | 957 std::string* error_desc) { |
| 907 *dtls = transport_channel_->IsDtlsActive(); | 958 *dtls = transport_channel_->IsDtlsActive(); |
| 908 if (*dtls && !cryptos.empty()) { | 959 if (*dtls && !cryptos.empty()) { |
| 909 SafeSetError("Cryptos must be empty when DTLS is active.", | 960 SafeSetError("Cryptos must be empty when DTLS is active.", |
| 910 error_desc); | 961 error_desc); |
| 911 return false; | 962 return false; |
| 912 } | 963 } |
| 913 return true; | 964 return true; |
| 914 } | 965 } |
| 915 | 966 |
| 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, | 967 bool BaseChannel::SetSrtp_w(const std::vector<CryptoParams>& cryptos, |
| 953 ContentAction action, | 968 ContentAction action, |
| 954 ContentSource src, | 969 ContentSource src, |
| 955 std::string* error_desc) { | 970 std::string* error_desc) { |
| 956 if (action == CA_UPDATE) { | 971 if (action == CA_UPDATE) { |
| 957 // no crypto params. | 972 // no crypto params. |
| 958 return true; | 973 return true; |
| 959 } | 974 } |
| 960 bool ret = false; | 975 bool ret = false; |
| 961 bool dtls = false; | 976 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(); | 1218 desc << "Failed to add remote stream ssrc: " << it->first_ssrc(); |
| 1204 SafeSetError(desc.str(), error_desc); | 1219 SafeSetError(desc.str(), error_desc); |
| 1205 ret = false; | 1220 ret = false; |
| 1206 } | 1221 } |
| 1207 } | 1222 } |
| 1208 } | 1223 } |
| 1209 remote_streams_ = streams; | 1224 remote_streams_ = streams; |
| 1210 return ret; | 1225 return ret; |
| 1211 } | 1226 } |
| 1212 | 1227 |
| 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( | 1228 void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension( |
| 1257 const std::vector<RtpHeaderExtension>& extensions) { | 1229 const std::vector<RtpHeaderExtension>& extensions) { |
| 1258 const RtpHeaderExtension* send_time_extension = | 1230 const RtpHeaderExtension* send_time_extension = |
| 1259 FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); | 1231 FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); |
| 1260 rtp_abs_sendtime_extn_id_ = | 1232 rtp_abs_sendtime_extn_id_ = |
| 1261 send_time_extension ? send_time_extension->id : -1; | 1233 send_time_extension ? send_time_extension->id : -1; |
| 1262 } | 1234 } |
| 1263 | 1235 |
| 1264 void BaseChannel::OnMessage(rtc::Message *pmsg) { | 1236 void BaseChannel::OnMessage(rtc::Message *pmsg) { |
| 1265 switch (pmsg->message_id) { | 1237 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"; | 1467 LOG(LS_INFO) << "Setting local voice description"; |
| 1496 | 1468 |
| 1497 const AudioContentDescription* audio = | 1469 const AudioContentDescription* audio = |
| 1498 static_cast<const AudioContentDescription*>(content); | 1470 static_cast<const AudioContentDescription*>(content); |
| 1499 ASSERT(audio != NULL); | 1471 ASSERT(audio != NULL); |
| 1500 if (!audio) { | 1472 if (!audio) { |
| 1501 SafeSetError("Can't find audio content in local description.", error_desc); | 1473 SafeSetError("Can't find audio content in local description.", error_desc); |
| 1502 return false; | 1474 return false; |
| 1503 } | 1475 } |
| 1504 | 1476 |
| 1505 bool ret = SetBaseLocalContent_w(content, action, error_desc); | 1477 if (!SetRtpTransportParameters_w(content, action, CS_LOCAL, error_desc)) { |
| 1506 // Set local audio codecs (what we want to receive). | 1478 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 } | 1479 } |
| 1515 | 1480 |
| 1516 // If everything worked, see if we can start receiving. | 1481 AudioRecvParameters recv_params = last_recv_params_; |
| 1517 if (ret) { | 1482 RtpParametersFromMediaDescription(audio, &recv_params); |
| 1518 std::vector<AudioCodec>::const_iterator it = audio->codecs().begin(); | 1483 if (!media_channel()->SetRecvParameters(recv_params)) { |
| 1519 for (; it != audio->codecs().end(); ++it) { | 1484 SafeSetError("Failed to set local video description recv parameters.", |
|
the sun
2015/08/04 14:32:18
s/video/audio
| |
| 1520 bundle_filter()->AddPayloadType(it->id); | 1485 error_desc); |
| 1521 } | 1486 return false; |
| 1522 ChangeState(); | |
| 1523 } else { | |
| 1524 LOG(LS_WARNING) << "Failed to set local voice description"; | |
| 1525 } | 1487 } |
| 1526 return ret; | 1488 for (const AudioCodec& codec : audio->codecs()) { |
| 1489 bundle_filter()->AddPayloadType(codec.id); | |
| 1490 } | |
| 1491 last_recv_params_ = recv_params; | |
| 1492 | |
| 1493 // TODO(pthatcher): Move local streams into AudioSendParameters, and | |
| 1494 // only give it to the media channel once we have a remote | |
| 1495 // description too (without a remote description, we won't be able | |
| 1496 // to send them anyway). | |
| 1497 if (!UpdateLocalStreams_w(audio->streams(), action, error_desc)) { | |
| 1498 SafeSetError("Failed to set local audio description streams.", error_desc); | |
| 1499 return false; | |
| 1500 } | |
| 1501 | |
| 1502 set_local_content_direction(content->direction()); | |
| 1503 ChangeState(); | |
| 1504 return true; | |
| 1527 } | 1505 } |
| 1528 | 1506 |
| 1529 bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content, | 1507 bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content, |
| 1530 ContentAction action, | 1508 ContentAction action, |
| 1531 std::string* error_desc) { | 1509 std::string* error_desc) { |
| 1532 ASSERT(worker_thread() == rtc::Thread::Current()); | 1510 ASSERT(worker_thread() == rtc::Thread::Current()); |
| 1533 LOG(LS_INFO) << "Setting remote voice description"; | 1511 LOG(LS_INFO) << "Setting remote voice description"; |
| 1534 | 1512 |
| 1535 const AudioContentDescription* audio = | 1513 const AudioContentDescription* audio = |
| 1536 static_cast<const AudioContentDescription*>(content); | 1514 static_cast<const AudioContentDescription*>(content); |
| 1537 ASSERT(audio != NULL); | 1515 ASSERT(audio != NULL); |
| 1538 if (!audio) { | 1516 if (!audio) { |
| 1539 SafeSetError("Can't find audio content in remote description.", error_desc); | 1517 SafeSetError("Can't find audio content in remote description.", error_desc); |
| 1540 return false; | 1518 return false; |
| 1541 } | 1519 } |
| 1542 | 1520 |
| 1543 bool ret = true; | 1521 if (!SetRtpTransportParameters_w(content, action, CS_REMOTE, error_desc)) { |
| 1544 // Set remote video codecs (what the other side wants to receive). | 1522 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 } | 1523 } |
| 1551 | 1524 |
| 1552 ret &= SetBaseRemoteContent_w(content, action, error_desc); | 1525 AudioSendParameters send_params = last_send_params_; |
| 1526 RtpSendParametersFromMediaDescription(audio, &send_params); | |
| 1527 if (audio->conference_mode()) { | |
| 1528 send_params.options.conference_mode.Set(true); | |
| 1529 } | |
| 1530 if (audio->agc_minus_10db()) { | |
| 1531 send_params.options.adjust_agc_delta.Set(kAgcMinus10db); | |
| 1532 } | |
| 1533 if (!media_channel()->SetSendParameters(send_params)) { | |
| 1534 SafeSetError("Failed to set remote audio description send parameters.", | |
| 1535 error_desc); | |
| 1536 return false; | |
| 1537 } | |
| 1538 last_send_params_ = send_params; | |
| 1553 | 1539 |
| 1554 if (action != CA_UPDATE) { | 1540 // TODO(pthatcher): Move remote streams into AudioRecvParameters, |
| 1555 // Tweak our audio processing settings, if needed. | 1541 // and only give it to the media channel once we have a local |
| 1556 AudioOptions audio_options; | 1542 // description too (without a local description, we won't be able to |
| 1557 if (!media_channel()->GetOptions(&audio_options)) { | 1543 // recv them anyway). |
| 1558 LOG(LS_WARNING) << "Can not set audio options from on remote content."; | 1544 if (!UpdateRemoteStreams_w(audio->streams(), action, error_desc)) { |
| 1559 } else { | 1545 SafeSetError("Failed to set remote audio description streams.", error_desc); |
| 1560 if (audio->conference_mode()) { | 1546 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 } | 1547 } |
| 1572 | 1548 |
| 1573 // If everything worked, see if we can start sending. | 1549 set_remote_content_direction(content->direction()); |
| 1574 if (ret) { | 1550 ChangeState(); |
| 1575 ChangeState(); | 1551 return true; |
| 1576 } else { | |
| 1577 LOG(LS_WARNING) << "Failed to set remote voice description"; | |
| 1578 } | |
| 1579 return ret; | |
| 1580 } | 1552 } |
| 1581 | 1553 |
| 1582 bool VoiceChannel::SetRingbackTone_w(const void* buf, int len) { | 1554 bool VoiceChannel::SetRingbackTone_w(const void* buf, int len) { |
| 1583 ASSERT(worker_thread() == rtc::Thread::Current()); | 1555 ASSERT(worker_thread() == rtc::Thread::Current()); |
| 1584 return media_channel()->SetRingbackTone(static_cast<const char*>(buf), len); | 1556 return media_channel()->SetRingbackTone(static_cast<const char*>(buf), len); |
| 1585 } | 1557 } |
| 1586 | 1558 |
| 1587 bool VoiceChannel::PlayRingbackTone_w(uint32 ssrc, bool play, bool loop) { | 1559 bool VoiceChannel::PlayRingbackTone_w(uint32 ssrc, bool play, bool loop) { |
| 1588 ASSERT(worker_thread() == rtc::Thread::Current()); | 1560 ASSERT(worker_thread() == rtc::Thread::Current()); |
| 1589 if (play) { | 1561 if (play) { |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1839 LOG(LS_INFO) << "Setting local video description"; | 1811 LOG(LS_INFO) << "Setting local video description"; |
| 1840 | 1812 |
| 1841 const VideoContentDescription* video = | 1813 const VideoContentDescription* video = |
| 1842 static_cast<const VideoContentDescription*>(content); | 1814 static_cast<const VideoContentDescription*>(content); |
| 1843 ASSERT(video != NULL); | 1815 ASSERT(video != NULL); |
| 1844 if (!video) { | 1816 if (!video) { |
| 1845 SafeSetError("Can't find video content in local description.", error_desc); | 1817 SafeSetError("Can't find video content in local description.", error_desc); |
| 1846 return false; | 1818 return false; |
| 1847 } | 1819 } |
| 1848 | 1820 |
| 1849 bool ret = SetBaseLocalContent_w(content, action, error_desc); | 1821 if (!SetRtpTransportParameters_w(content, action, CS_LOCAL, error_desc)) { |
| 1850 // Set local video codecs (what we want to receive). | 1822 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 } | 1823 } |
| 1857 | 1824 |
| 1858 if (action != CA_UPDATE) { | 1825 VideoRecvParameters recv_params = last_recv_params_; |
| 1859 VideoOptions video_options; | 1826 RtpParametersFromMediaDescription(video, &recv_params); |
| 1860 media_channel()->GetOptions(&video_options); | 1827 if (!media_channel()->SetRecvParameters(recv_params)) { |
| 1861 if (!media_channel()->SetOptions(video_options)) { | 1828 SafeSetError("Failed to set local video description recv parameters.", |
| 1862 // Log an error on failure, but don't abort the call. | 1829 error_desc); |
| 1863 LOG(LS_ERROR) << "Failed to set video channel options"; | 1830 return false; |
| 1864 } | 1831 } |
| 1832 for (const VideoCodec& codec : video->codecs()) { | |
| 1833 bundle_filter()->AddPayloadType(codec.id); | |
| 1834 } | |
| 1835 last_recv_params_ = recv_params; | |
| 1836 | |
| 1837 // TODO(pthatcher): Move local streams into VideoSendParameters, and | |
| 1838 // only give it to the media channel once we have a remote | |
| 1839 // description too (without a remote description, we won't be able | |
| 1840 // to send them anyway). | |
| 1841 if (!UpdateLocalStreams_w(video->streams(), action, error_desc)) { | |
| 1842 SafeSetError("Failed to set local video description streams.", error_desc); | |
| 1843 return false; | |
| 1865 } | 1844 } |
| 1866 | 1845 |
| 1867 // If everything worked, see if we can start receiving. | 1846 set_local_content_direction(content->direction()); |
| 1868 if (ret) { | 1847 ChangeState(); |
| 1869 std::vector<VideoCodec>::const_iterator it = video->codecs().begin(); | 1848 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 } | 1849 } |
| 1879 | 1850 |
| 1880 bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content, | 1851 bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content, |
| 1881 ContentAction action, | 1852 ContentAction action, |
| 1882 std::string* error_desc) { | 1853 std::string* error_desc) { |
| 1883 ASSERT(worker_thread() == rtc::Thread::Current()); | 1854 ASSERT(worker_thread() == rtc::Thread::Current()); |
| 1884 LOG(LS_INFO) << "Setting remote video description"; | 1855 LOG(LS_INFO) << "Setting remote video description"; |
| 1885 | 1856 |
| 1886 const VideoContentDescription* video = | 1857 const VideoContentDescription* video = |
| 1887 static_cast<const VideoContentDescription*>(content); | 1858 static_cast<const VideoContentDescription*>(content); |
| 1888 ASSERT(video != NULL); | 1859 ASSERT(video != NULL); |
| 1889 if (!video) { | 1860 if (!video) { |
| 1890 SafeSetError("Can't find video content in remote description.", error_desc); | 1861 SafeSetError("Can't find video content in remote description.", error_desc); |
| 1891 return false; | 1862 return false; |
| 1892 } | 1863 } |
| 1893 | 1864 |
| 1894 bool ret = true; | 1865 |
| 1895 // Set remote video codecs (what the other side wants to receive). | 1866 if (!SetRtpTransportParameters_w(content, action, CS_REMOTE, error_desc)) { |
| 1896 if (action != CA_UPDATE || video->has_codecs()) { | 1867 return false; |
| 1897 if (!media_channel()->SetSendCodecs(video->codecs())) { | |
| 1898 SafeSetError("Failed to set video send codecs.", error_desc); | |
| 1899 ret = false; | |
| 1900 } | |
| 1901 } | 1868 } |
| 1902 | 1869 |
| 1903 ret &= SetBaseRemoteContent_w(content, action, error_desc); | 1870 VideoSendParameters send_params = last_send_params_; |
| 1871 RtpSendParametersFromMediaDescription(video, &send_params); | |
| 1872 if (video->conference_mode()) { | |
| 1873 send_params.options.conference_mode.Set(true); | |
| 1874 } | |
| 1875 if (!media_channel()->SetSendParameters(send_params)) { | |
| 1876 SafeSetError("Failed to set remote video description send parameters.", | |
| 1877 error_desc); | |
| 1878 return false; | |
| 1879 } | |
| 1880 last_send_params_ = send_params; | |
| 1904 | 1881 |
| 1905 if (action != CA_UPDATE) { | 1882 // TODO(pthatcher): Move remote streams into VideoRecvParameters, |
| 1906 // Tweak our video processing settings, if needed. | 1883 // and only give it to the media channel once we have a local |
| 1907 VideoOptions video_options; | 1884 // description too (without a local description, we won't be able to |
| 1908 media_channel()->GetOptions(&video_options); | 1885 // recv them anyway). |
| 1909 if (video->conference_mode()) { | 1886 if (!UpdateRemoteStreams_w(video->streams(), action, error_desc)) { |
| 1910 video_options.conference_mode.Set(true); | 1887 SafeSetError("Failed to set remote video description streams.", error_desc); |
| 1911 } | 1888 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 } | 1889 } |
| 1918 | 1890 |
| 1919 // If everything worked, see if we can start sending. | 1891 if (video->rtp_header_extensions_set()) { |
| 1920 if (ret) { | 1892 MaybeCacheRtpAbsSendTimeHeaderExtension(video->rtp_header_extensions()); |
|
the sun
2015/08/04 14:32:18
Looks like this must be done for audio too.
| |
| 1921 ChangeState(); | |
| 1922 } else { | |
| 1923 LOG(LS_WARNING) << "Failed to set remote video description"; | |
| 1924 } | 1893 } |
| 1925 return ret; | 1894 |
| 1895 set_remote_content_direction(content->direction()); | |
| 1896 ChangeState(); | |
| 1897 return true; | |
| 1926 } | 1898 } |
| 1927 | 1899 |
| 1928 bool VideoChannel::ApplyViewRequest_w(const ViewRequest& request) { | 1900 bool VideoChannel::ApplyViewRequest_w(const ViewRequest& request) { |
| 1929 bool ret = true; | 1901 bool ret = true; |
| 1930 // Set the send format for each of the local streams. If the view request | 1902 // 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 | 1903 // does not contain a local stream, set its send format to 0x0, which will |
| 1932 // drop all frames. | 1904 // drop all frames. |
| 1933 for (std::vector<StreamParams>::const_iterator it = local_streams().begin(); | 1905 for (std::vector<StreamParams>::const_iterator it = local_streams().begin(); |
| 1934 it != local_streams().end(); ++it) { | 1906 it != local_streams().end(); ++it) { |
| 1935 VideoFormat format(0, 0, 0, cricket::FOURCC_I420); | 1907 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"; | 2192 LOG(LS_INFO) << "Setting local data description"; |
| 2221 | 2193 |
| 2222 const DataContentDescription* data = | 2194 const DataContentDescription* data = |
| 2223 static_cast<const DataContentDescription*>(content); | 2195 static_cast<const DataContentDescription*>(content); |
| 2224 ASSERT(data != NULL); | 2196 ASSERT(data != NULL); |
| 2225 if (!data) { | 2197 if (!data) { |
| 2226 SafeSetError("Can't find data content in local description.", error_desc); | 2198 SafeSetError("Can't find data content in local description.", error_desc); |
| 2227 return false; | 2199 return false; |
| 2228 } | 2200 } |
| 2229 | 2201 |
| 2230 bool ret = false; | |
| 2231 if (!SetDataChannelTypeFromContent(data, error_desc)) { | 2202 if (!SetDataChannelTypeFromContent(data, error_desc)) { |
| 2232 return false; | 2203 return false; |
| 2233 } | 2204 } |
| 2234 | 2205 |
| 2235 if (data_channel_type_ == DCT_SCTP) { | 2206 if (data_channel_type_ == DCT_RTP) { |
| 2236 // SCTP data channels don't need the rest of the stuff. | 2207 if (!SetRtpTransportParameters_w(content, action, CS_LOCAL, error_desc)) { |
| 2237 ret = UpdateLocalStreams_w(data->streams(), action, error_desc); | 2208 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 } | 2209 } |
| 2255 } | 2210 } |
| 2256 | 2211 |
| 2257 // If everything worked, see if we can start receiving. | 2212 // FYI: We send the SCTP port number (not to be confused with the |
| 2258 if (ret) { | 2213 // underlying UDP port number) as a codec parameter. So even SCTP |
| 2259 std::vector<DataCodec>::const_iterator it = data->codecs().begin(); | 2214 // data channels need codecs. |
| 2260 for (; it != data->codecs().end(); ++it) { | 2215 DataRecvParameters recv_params = last_recv_params_; |
| 2261 bundle_filter()->AddPayloadType(it->id); | 2216 RtpParametersFromMediaDescription(data, &recv_params); |
| 2217 if (!media_channel()->SetRecvParameters(recv_params)) { | |
| 2218 SafeSetError("Failed to set remote data description recv parameters.", | |
| 2219 error_desc); | |
| 2220 return false; | |
| 2221 } | |
| 2222 if (data_channel_type_ == DCT_RTP) { | |
| 2223 for (const DataCodec& codec : data->codecs()) { | |
| 2224 bundle_filter()->AddPayloadType(codec.id); | |
| 2262 } | 2225 } |
| 2263 ChangeState(); | |
| 2264 } else { | |
| 2265 LOG(LS_WARNING) << "Failed to set local data description"; | |
| 2266 } | 2226 } |
| 2267 return ret; | 2227 last_recv_params_ = recv_params; |
| 2228 | |
| 2229 // TODO(pthatcher): Move local streams into DataSendParameters, and | |
| 2230 // only give it to the media channel once we have a remote | |
| 2231 // description too (without a remote description, we won't be able | |
| 2232 // to send them anyway). | |
| 2233 if (!UpdateLocalStreams_w(data->streams(), action, error_desc)) { | |
| 2234 SafeSetError("Failed to set local data description streams.", error_desc); | |
| 2235 return false; | |
| 2236 } | |
| 2237 | |
| 2238 set_local_content_direction(content->direction()); | |
| 2239 ChangeState(); | |
| 2240 return true; | |
| 2268 } | 2241 } |
| 2269 | 2242 |
| 2270 bool DataChannel::SetRemoteContent_w(const MediaContentDescription* content, | 2243 bool DataChannel::SetRemoteContent_w(const MediaContentDescription* content, |
| 2271 ContentAction action, | 2244 ContentAction action, |
| 2272 std::string* error_desc) { | 2245 std::string* error_desc) { |
| 2273 ASSERT(worker_thread() == rtc::Thread::Current()); | 2246 ASSERT(worker_thread() == rtc::Thread::Current()); |
| 2274 | 2247 |
| 2275 const DataContentDescription* data = | 2248 const DataContentDescription* data = |
| 2276 static_cast<const DataContentDescription*>(content); | 2249 static_cast<const DataContentDescription*>(content); |
| 2277 ASSERT(data != NULL); | 2250 ASSERT(data != NULL); |
| 2278 if (!data) { | 2251 if (!data) { |
| 2279 SafeSetError("Can't find data content in remote description.", error_desc); | 2252 SafeSetError("Can't find data content in remote description.", error_desc); |
| 2280 return false; | 2253 return false; |
| 2281 } | 2254 } |
| 2282 | 2255 |
| 2283 bool ret = true; | 2256 // If the remote data doesn't have codecs and isn't an update, it |
| 2257 // must be empty, so ignore it. | |
| 2258 if (!data->has_codecs() && action != CA_UPDATE) { | |
| 2259 return true; | |
| 2260 } | |
| 2261 | |
| 2284 if (!SetDataChannelTypeFromContent(data, error_desc)) { | 2262 if (!SetDataChannelTypeFromContent(data, error_desc)) { |
| 2285 return false; | 2263 return false; |
| 2286 } | 2264 } |
| 2287 | 2265 |
| 2288 if (data_channel_type_ == DCT_SCTP) { | 2266 LOG(LS_INFO) << "Setting remote data description"; |
| 2289 LOG(LS_INFO) << "Setting SCTP remote data description"; | 2267 if (data_channel_type_ == DCT_RTP && |
| 2290 // SCTP data channels don't need the rest of the stuff. | 2268 !SetRtpTransportParameters_w(content, action, CS_REMOTE, error_desc)) { |
| 2291 ret = UpdateRemoteStreams_w(content->streams(), action, error_desc); | 2269 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 } | 2270 } |
| 2331 | 2271 |
| 2332 // If everything worked, see if we can start sending. | 2272 |
| 2333 if (ret) { | 2273 DataSendParameters send_params = last_send_params_; |
| 2334 ChangeState(); | 2274 RtpSendParametersFromMediaDescription<DataCodec>(data, &send_params); |
| 2335 } else { | 2275 if (!media_channel()->SetSendParameters(send_params)) { |
| 2336 LOG(LS_WARNING) << "Failed to set remote data description"; | 2276 SafeSetError("Failed to set remote data description send parameters.", |
| 2277 error_desc); | |
| 2278 return false; | |
| 2337 } | 2279 } |
| 2338 return ret; | 2280 last_send_params_ = send_params; |
| 2281 | |
| 2282 // TODO(pthatcher): Move remote streams into DataRecvParameters, | |
| 2283 // and only give it to the media channel once we have a local | |
| 2284 // description too (without a local description, we won't be able to | |
| 2285 // recv them anyway). | |
| 2286 if (!UpdateRemoteStreams_w(data->streams(), action, error_desc)) { | |
| 2287 SafeSetError("Failed to set remote data description streams.", | |
| 2288 error_desc); | |
| 2289 return false; | |
| 2290 } | |
| 2291 | |
| 2292 set_remote_content_direction(content->direction()); | |
| 2293 ChangeState(); | |
| 2294 return true; | |
| 2339 } | 2295 } |
| 2340 | 2296 |
| 2341 void DataChannel::ChangeState() { | 2297 void DataChannel::ChangeState() { |
| 2342 // Render incoming data if we're the active call, and we have the local | 2298 // 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. | 2299 // content. We receive data on the default channel and multiplexed streams. |
| 2344 bool recv = IsReadyToReceive(); | 2300 bool recv = IsReadyToReceive(); |
| 2345 if (!media_channel()->SetReceive(recv)) { | 2301 if (!media_channel()->SetReceive(recv)) { |
| 2346 LOG(LS_ERROR) << "Failed to SetReceive on data channel"; | 2302 LOG(LS_ERROR) << "Failed to SetReceive on data channel"; |
| 2347 } | 2303 } |
| 2348 | 2304 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2476 return (data_channel_type_ == DCT_RTP); | 2432 return (data_channel_type_ == DCT_RTP); |
| 2477 } | 2433 } |
| 2478 | 2434 |
| 2479 void DataChannel::OnStreamClosedRemotely(uint32 sid) { | 2435 void DataChannel::OnStreamClosedRemotely(uint32 sid) { |
| 2480 rtc::TypedMessageData<uint32>* message = | 2436 rtc::TypedMessageData<uint32>* message = |
| 2481 new rtc::TypedMessageData<uint32>(sid); | 2437 new rtc::TypedMessageData<uint32>(sid); |
| 2482 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); | 2438 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); |
| 2483 } | 2439 } |
| 2484 | 2440 |
| 2485 } // namespace cricket | 2441 } // namespace cricket |
| OLD | NEW |