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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 47 #include "webrtc/base/byteorder.h" | 47 #include "webrtc/base/byteorder.h" |
| 48 #include "webrtc/base/common.h" | 48 #include "webrtc/base/common.h" |
| 49 #include "webrtc/base/helpers.h" | 49 #include "webrtc/base/helpers.h" |
| 50 #include "webrtc/base/logging.h" | 50 #include "webrtc/base/logging.h" |
| 51 #include "webrtc/base/stringencode.h" | 51 #include "webrtc/base/stringencode.h" |
| 52 #include "webrtc/base/stringutils.h" | 52 #include "webrtc/base/stringutils.h" |
| 53 #include "webrtc/common.h" | 53 #include "webrtc/common.h" |
| 54 #include "webrtc/modules/audio_processing/include/audio_processing.h" | 54 #include "webrtc/modules/audio_processing/include/audio_processing.h" |
| 55 | 55 |
| 56 namespace cricket { | 56 namespace cricket { |
| 57 namespace { | |
| 57 | 58 |
| 58 static const int kMaxNumPacketSize = 6; | 59 const int kMaxNumPacketSize = 6; |
| 59 struct CodecPref { | 60 struct CodecPref { |
| 60 const char* name; | 61 const char* name; |
| 61 int clockrate; | 62 int clockrate; |
| 62 int channels; | 63 int channels; |
| 63 int payload_type; | 64 int payload_type; |
| 64 bool is_multi_rate; | 65 bool is_multi_rate; |
| 65 int packet_sizes_ms[kMaxNumPacketSize]; | 66 int packet_sizes_ms[kMaxNumPacketSize]; |
| 66 }; | 67 }; |
| 67 // Note: keep the supported packet sizes in ascending order. | 68 // Note: keep the supported packet sizes in ascending order. |
| 68 static const CodecPref kCodecPrefs[] = { | 69 const CodecPref kCodecPrefs[] = { |
| 69 { kOpusCodecName, 48000, 2, 111, true, { 10, 20, 40, 60 } }, | 70 { kOpusCodecName, 48000, 2, 111, true, { 10, 20, 40, 60 } }, |
| 70 { kIsacCodecName, 16000, 1, 103, true, { 30, 60 } }, | 71 { kIsacCodecName, 16000, 1, 103, true, { 30, 60 } }, |
| 71 { kIsacCodecName, 32000, 1, 104, true, { 30 } }, | 72 { kIsacCodecName, 32000, 1, 104, true, { 30 } }, |
| 72 // G722 should be advertised as 8000 Hz because of the RFC "bug". | 73 // G722 should be advertised as 8000 Hz because of the RFC "bug". |
| 73 { kG722CodecName, 8000, 1, 9, false, { 10, 20, 30, 40, 50, 60 } }, | 74 { kG722CodecName, 8000, 1, 9, false, { 10, 20, 30, 40, 50, 60 } }, |
| 74 { kIlbcCodecName, 8000, 1, 102, false, { 20, 30, 40, 60 } }, | 75 { kIlbcCodecName, 8000, 1, 102, false, { 20, 30, 40, 60 } }, |
| 75 { kPcmuCodecName, 8000, 1, 0, false, { 10, 20, 30, 40, 50, 60 } }, | 76 { kPcmuCodecName, 8000, 1, 0, false, { 10, 20, 30, 40, 50, 60 } }, |
| 76 { kPcmaCodecName, 8000, 1, 8, false, { 10, 20, 30, 40, 50, 60 } }, | 77 { kPcmaCodecName, 8000, 1, 8, false, { 10, 20, 30, 40, 50, 60 } }, |
| 77 { kCnCodecName, 32000, 1, 106, false, { } }, | 78 { kCnCodecName, 32000, 1, 106, false, { } }, |
| 78 { kCnCodecName, 16000, 1, 105, false, { } }, | 79 { kCnCodecName, 16000, 1, 105, false, { } }, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 90 // | 91 // |
| 91 // On Windows systems which only support Wave Audio style default, uses either | 92 // On Windows systems which only support Wave Audio style default, uses either |
| 92 // -1 or 0 to select the default device. | 93 // -1 or 0 to select the default device. |
| 93 // | 94 // |
| 94 // On Windows systems which support both "Default Communication Device" and | 95 // On Windows systems which support both "Default Communication Device" and |
| 95 // old Wave Audio style default, use -1 for Default Communications Device and | 96 // old Wave Audio style default, use -1 for Default Communications Device and |
| 96 // -2 for Wave Audio style default, which is what we want to use for clips. | 97 // -2 for Wave Audio style default, which is what we want to use for clips. |
| 97 // It's not clear yet whether the -2 index is handled properly on other OSes. | 98 // It's not clear yet whether the -2 index is handled properly on other OSes. |
| 98 | 99 |
| 99 #ifdef WIN32 | 100 #ifdef WIN32 |
| 100 static const int kDefaultAudioDeviceId = -1; | 101 const int kDefaultAudioDeviceId = -1; |
| 101 #else | 102 #else |
| 102 static const int kDefaultAudioDeviceId = 0; | 103 const int kDefaultAudioDeviceId = 0; |
| 103 #endif | 104 #endif |
| 104 | 105 |
| 105 // Parameter used for NACK. | 106 // Parameter used for NACK. |
| 106 // This value is equivalent to 5 seconds of audio data at 20 ms per packet. | 107 // This value is equivalent to 5 seconds of audio data at 20 ms per packet. |
| 107 static const int kNackMaxPackets = 250; | 108 const int kNackMaxPackets = 250; |
| 108 | 109 |
| 109 // Codec parameters for Opus. | 110 // Codec parameters for Opus. |
| 110 // draft-spittka-payload-rtp-opus-03 | 111 // draft-spittka-payload-rtp-opus-03 |
| 111 | 112 |
| 112 // Recommended bitrates: | 113 // Recommended bitrates: |
| 113 // 8-12 kb/s for NB speech, | 114 // 8-12 kb/s for NB speech, |
| 114 // 16-20 kb/s for WB speech, | 115 // 16-20 kb/s for WB speech, |
| 115 // 28-40 kb/s for FB speech, | 116 // 28-40 kb/s for FB speech, |
| 116 // 48-64 kb/s for FB mono music, and | 117 // 48-64 kb/s for FB mono music, and |
| 117 // 64-128 kb/s for FB stereo music. | 118 // 64-128 kb/s for FB stereo music. |
| 118 // The current implementation applies the following values to mono signals, | 119 // The current implementation applies the following values to mono signals, |
| 119 // and multiplies them by 2 for stereo. | 120 // and multiplies them by 2 for stereo. |
| 120 static const int kOpusBitrateNb = 12000; | 121 const int kOpusBitrateNb = 12000; |
| 121 static const int kOpusBitrateWb = 20000; | 122 const int kOpusBitrateWb = 20000; |
| 122 static const int kOpusBitrateFb = 32000; | 123 const int kOpusBitrateFb = 32000; |
| 123 | 124 |
| 124 // Opus bitrate should be in the range between 6000 and 510000. | 125 // Opus bitrate should be in the range between 6000 and 510000. |
| 125 static const int kOpusMinBitrate = 6000; | 126 const int kOpusMinBitrate = 6000; |
| 126 static const int kOpusMaxBitrate = 510000; | 127 const int kOpusMaxBitrate = 510000; |
| 127 | 128 |
| 128 // Default audio dscp value. | 129 // Default audio dscp value. |
| 129 // See http://tools.ietf.org/html/rfc2474 for details. | 130 // See http://tools.ietf.org/html/rfc2474 for details. |
| 130 // See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00 | 131 // See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00 |
| 131 static const rtc::DiffServCodePoint kAudioDscpValue = rtc::DSCP_EF; | 132 const rtc::DiffServCodePoint kAudioDscpValue = rtc::DSCP_EF; |
| 132 | 133 |
| 133 // Ensure we open the file in a writeable path on ChromeOS and Android. This | 134 // Ensure we open the file in a writeable path on ChromeOS and Android. This |
| 134 // workaround can be removed when it's possible to specify a filename for audio | 135 // workaround can be removed when it's possible to specify a filename for audio |
| 135 // option based AEC dumps. | 136 // option based AEC dumps. |
| 136 // | 137 // |
| 137 // TODO(grunell): Use a string in the options instead of hardcoding it here | 138 // TODO(grunell): Use a string in the options instead of hardcoding it here |
| 138 // and let the embedder choose the filename (crbug.com/264223). | 139 // and let the embedder choose the filename (crbug.com/264223). |
| 139 // | 140 // |
| 140 // NOTE(ajm): Don't use hardcoded paths on platforms not explicitly specified | 141 // NOTE(ajm): Don't use hardcoded paths on platforms not explicitly specified |
| 141 // below. | 142 // below. |
| 142 #if defined(CHROMEOS) | 143 #if defined(CHROMEOS) |
| 143 static const char kAecDumpByAudioOptionFilename[] = "/tmp/audio.aecdump"; | 144 const char kAecDumpByAudioOptionFilename[] = "/tmp/audio.aecdump"; |
| 144 #elif defined(ANDROID) | 145 #elif defined(ANDROID) |
| 145 static const char kAecDumpByAudioOptionFilename[] = "/sdcard/audio.aecdump"; | 146 const char kAecDumpByAudioOptionFilename[] = "/sdcard/audio.aecdump"; |
| 146 #else | 147 #else |
| 147 static const char kAecDumpByAudioOptionFilename[] = "audio.aecdump"; | 148 const char kAecDumpByAudioOptionFilename[] = "audio.aecdump"; |
| 148 #endif | 149 #endif |
| 149 | 150 |
| 150 namespace { | 151 // See: https://code.google.com/p/webrtc/issues/detail?id=4740 |
| 152 const int kDefaultRtcpReceiverReportSsrc = 1; | |
| 151 | 153 |
| 152 bool ValidateStreamParams(const StreamParams& sp) { | 154 bool ValidateStreamParams(const StreamParams& sp) { |
| 153 if (sp.ssrcs.empty()) { | 155 if (sp.ssrcs.empty()) { |
| 154 LOG(LS_ERROR) << "No SSRCs in stream parameters: " << sp.ToString(); | 156 LOG(LS_ERROR) << "No SSRCs in stream parameters: " << sp.ToString(); |
| 155 return false; | 157 return false; |
| 156 } | 158 } |
| 157 if (sp.ssrcs.size() > 1) { | 159 if (sp.ssrcs.size() > 1) { |
| 158 LOG(LS_ERROR) << "Multiple SSRCs in stream parameters: " << sp.ToString(); | 160 LOG(LS_ERROR) << "Multiple SSRCs in stream parameters: " << sp.ToString(); |
| 159 return false; | 161 return false; |
| 160 } | 162 } |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 572 LOG(LS_INFO) << "WebRtcVoiceEngine::Terminate"; | 574 LOG(LS_INFO) << "WebRtcVoiceEngine::Terminate"; |
| 573 initialized_ = false; | 575 initialized_ = false; |
| 574 | 576 |
| 575 StopAecDump(); | 577 StopAecDump(); |
| 576 | 578 |
| 577 voe_wrapper_->base()->Terminate(); | 579 voe_wrapper_->base()->Terminate(); |
| 578 } | 580 } |
| 579 | 581 |
| 580 VoiceMediaChannel* WebRtcVoiceEngine::CreateChannel(webrtc::Call* call, | 582 VoiceMediaChannel* WebRtcVoiceEngine::CreateChannel(webrtc::Call* call, |
| 581 const AudioOptions& options) { | 583 const AudioOptions& options) { |
| 582 WebRtcVoiceMediaChannel* ch = | 584 return new WebRtcVoiceMediaChannel(this, options, call); |
| 583 new WebRtcVoiceMediaChannel(this, options, call); | |
| 584 if (!ch->valid()) { | |
| 585 delete ch; | |
| 586 return nullptr; | |
| 587 } | |
| 588 return ch; | |
| 589 } | 585 } |
| 590 | 586 |
| 591 bool WebRtcVoiceEngine::SetOptions(const AudioOptions& options) { | 587 bool WebRtcVoiceEngine::SetOptions(const AudioOptions& options) { |
| 592 if (!ApplyOptions(options)) { | 588 if (!ApplyOptions(options)) { |
| 593 return false; | 589 return false; |
| 594 } | 590 } |
| 595 options_ = options; | 591 options_ = options; |
| 596 return true; | 592 return true; |
| 597 } | 593 } |
| 598 | 594 |
| (...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1303 if (is_dumping_aec_) { | 1299 if (is_dumping_aec_) { |
| 1304 // Stop dumping AEC when we are dumping. | 1300 // Stop dumping AEC when we are dumping. |
| 1305 if (voe_wrapper_->processing()->StopDebugRecording() != | 1301 if (voe_wrapper_->processing()->StopDebugRecording() != |
| 1306 webrtc::AudioProcessing::kNoError) { | 1302 webrtc::AudioProcessing::kNoError) { |
| 1307 LOG_RTCERR0(StopDebugRecording); | 1303 LOG_RTCERR0(StopDebugRecording); |
| 1308 } | 1304 } |
| 1309 is_dumping_aec_ = false; | 1305 is_dumping_aec_ = false; |
| 1310 } | 1306 } |
| 1311 } | 1307 } |
| 1312 | 1308 |
| 1313 int WebRtcVoiceEngine::CreateVoiceChannel(VoEWrapper* voice_engine_wrapper) { | 1309 int WebRtcVoiceEngine::CreateVoiceChannel() { |
|
pthatcher1
2015/10/01 19:57:56
Can we rename this CreateVoeChannel?
the sun
2015/10/13 15:07:03
Done.
| |
| 1314 return voice_engine_wrapper->base()->CreateChannel(voe_config_); | 1310 return voe_wrapper_->base()->CreateChannel(voe_config_); |
| 1315 } | |
| 1316 | |
| 1317 int WebRtcVoiceEngine::CreateMediaVoiceChannel() { | |
| 1318 return CreateVoiceChannel(voe_wrapper_.get()); | |
| 1319 } | 1311 } |
| 1320 | 1312 |
| 1321 class WebRtcVoiceMediaChannel::WebRtcVoiceChannelRenderer | 1313 class WebRtcVoiceMediaChannel::WebRtcVoiceChannelRenderer |
| 1322 : public AudioRenderer::Sink { | 1314 : public AudioRenderer::Sink { |
| 1323 public: | 1315 public: |
| 1324 WebRtcVoiceChannelRenderer(int ch, | 1316 WebRtcVoiceChannelRenderer(int ch, |
| 1325 webrtc::AudioTransport* voe_audio_transport) | 1317 webrtc::AudioTransport* voe_audio_transport) |
| 1326 : channel_(ch), | 1318 : channel_(ch), |
| 1327 voe_audio_transport_(voe_audio_transport), | 1319 voe_audio_transport_(voe_audio_transport), |
| 1328 renderer_(NULL) {} | 1320 renderer_(NULL) {} |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1398 | 1390 |
| 1399 // Protects |renderer_| in Start(), Stop() and OnClose(). | 1391 // Protects |renderer_| in Start(), Stop() and OnClose(). |
| 1400 rtc::CriticalSection lock_; | 1392 rtc::CriticalSection lock_; |
| 1401 }; | 1393 }; |
| 1402 | 1394 |
| 1403 // WebRtcVoiceMediaChannel | 1395 // WebRtcVoiceMediaChannel |
| 1404 WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine, | 1396 WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine, |
| 1405 const AudioOptions& options, | 1397 const AudioOptions& options, |
| 1406 webrtc::Call* call) | 1398 webrtc::Call* call) |
| 1407 : engine_(engine), | 1399 : engine_(engine), |
| 1408 voe_channel_(engine->CreateMediaVoiceChannel()), | |
| 1409 send_bitrate_setting_(false), | 1400 send_bitrate_setting_(false), |
| 1410 send_bitrate_bps_(0), | 1401 send_bitrate_bps_(0), |
| 1411 options_(), | 1402 options_(), |
| 1412 dtmf_allowed_(false), | 1403 dtmf_allowed_(false), |
| 1413 desired_playout_(false), | 1404 desired_playout_(false), |
| 1414 nack_enabled_(false), | 1405 nack_enabled_(false), |
| 1415 playout_(false), | 1406 playout_(false), |
| 1416 typing_noise_detected_(false), | 1407 typing_noise_detected_(false), |
| 1417 desired_send_(SEND_NOTHING), | 1408 desired_send_(SEND_NOTHING), |
| 1418 send_(SEND_NOTHING), | 1409 send_(SEND_NOTHING), |
| 1419 call_(call), | 1410 call_(call), |
| 1420 default_recv_ssrc_(0), | 1411 default_recv_ssrc_(0), |
| 1421 default_recv_channel_id_(-1) { | 1412 default_recv_channel_id_(-1) { |
| 1413 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel"; | |
| 1414 RTC_DCHECK(nullptr != call); | |
| 1422 engine->RegisterChannel(this); | 1415 engine->RegisterChannel(this); |
| 1423 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel " | |
| 1424 << voe_channel(); | |
| 1425 RTC_DCHECK(nullptr != call); | |
| 1426 ConfigureSendChannel(voe_channel()); | |
| 1427 SetOptions(options); | 1416 SetOptions(options); |
| 1428 } | 1417 } |
| 1429 | 1418 |
| 1430 WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() { | 1419 WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() { |
| 1431 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel " | 1420 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel"; |
| 1432 << voe_channel(); | |
| 1433 | 1421 |
| 1434 // Remove any remaining send streams, the default channel will be deleted | 1422 // Remove any remaining send streams. |
| 1435 // later. | |
| 1436 while (!send_channels_.empty()) { | 1423 while (!send_channels_.empty()) { |
| 1437 RemoveSendStream(send_channels_.begin()->first); | 1424 RemoveSendStream(send_channels_.begin()->first); |
| 1438 } | 1425 } |
| 1439 | 1426 |
| 1440 // Unregister ourselves from the engine. | 1427 // Remove any remaining receive streams. |
| 1441 engine()->UnregisterChannel(this); | |
| 1442 | |
| 1443 // Remove any remaining streams. | |
| 1444 while (!receive_channels_.empty()) { | 1428 while (!receive_channels_.empty()) { |
| 1445 RemoveRecvStream(receive_channels_.begin()->first); | 1429 RemoveRecvStream(receive_channels_.begin()->first); |
| 1446 } | 1430 } |
| 1447 RTC_DCHECK(receive_streams_.empty()); | 1431 RTC_DCHECK(receive_streams_.empty()); |
| 1448 | 1432 |
| 1449 // Delete the default channel. | 1433 // Unregister ourselves from the engine. |
| 1450 DeleteChannel(voe_channel()); | 1434 engine()->UnregisterChannel(this); |
| 1451 } | 1435 } |
| 1452 | 1436 |
| 1453 bool WebRtcVoiceMediaChannel::SetSendParameters( | 1437 bool WebRtcVoiceMediaChannel::SetSendParameters( |
| 1454 const AudioSendParameters& params) { | 1438 const AudioSendParameters& params) { |
| 1455 // TODO(pthatcher): Refactor this to be more clean now that we have | 1439 // TODO(pthatcher): Refactor this to be more clean now that we have |
| 1456 // all the information at once. | 1440 // all the information at once. |
| 1457 return (SetSendCodecs(params.codecs) && | 1441 return (SetSendCodecs(params.codecs) && |
| 1458 SetSendRtpHeaderExtensions(params.extensions) && | 1442 SetSendRtpHeaderExtensions(params.extensions) && |
| 1459 SetMaxSendBandwidth(params.max_bandwidth_bps) && | 1443 SetMaxSendBandwidth(params.max_bandwidth_bps) && |
| 1460 SetOptions(params.options)); | 1444 SetOptions(params.options)); |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1959 | 1943 |
| 1960 return true; | 1944 return true; |
| 1961 } | 1945 } |
| 1962 | 1946 |
| 1963 bool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions( | 1947 bool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions( |
| 1964 const std::vector<RtpHeaderExtension>& extensions) { | 1948 const std::vector<RtpHeaderExtension>& extensions) { |
| 1965 if (send_extensions_ == extensions) { | 1949 if (send_extensions_ == extensions) { |
| 1966 return true; | 1950 return true; |
| 1967 } | 1951 } |
| 1968 | 1952 |
| 1969 // The default channel may or may not be in |send_channels_|. Set the rtp | |
| 1970 // header extensions for default channel regardless. | |
| 1971 | |
| 1972 if (!SetChannelSendRtpHeaderExtensions(voe_channel(), extensions)) { | |
| 1973 return false; | |
| 1974 } | |
| 1975 | |
| 1976 // Loop through all send channels and enable/disable the extensions. | 1953 // Loop through all send channels and enable/disable the extensions. |
| 1977 for (const auto& ch : send_channels_) { | 1954 for (const auto& ch : send_channels_) { |
| 1978 if (!SetChannelSendRtpHeaderExtensions(ch.second->channel(), extensions)) { | 1955 if (!SetChannelSendRtpHeaderExtensions(ch.second->channel(), extensions)) { |
| 1979 return false; | 1956 return false; |
| 1980 } | 1957 } |
| 1981 } | 1958 } |
| 1982 | 1959 |
| 1983 send_extensions_ = extensions; | 1960 send_extensions_ = extensions; |
| 1984 return true; | 1961 return true; |
| 1985 } | 1962 } |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2112 } | 2089 } |
| 2113 if (!MuteStream(ssrc, !enable)) { | 2090 if (!MuteStream(ssrc, !enable)) { |
| 2114 return false; | 2091 return false; |
| 2115 } | 2092 } |
| 2116 if (enable && options) { | 2093 if (enable && options) { |
| 2117 return SetOptions(*options); | 2094 return SetOptions(*options); |
| 2118 } | 2095 } |
| 2119 return true; | 2096 return true; |
| 2120 } | 2097 } |
| 2121 | 2098 |
| 2122 // TODO(ronghuawu): Change this method to return bool. | 2099 int WebRtcVoiceMediaChannel::CreateChannel() { |
|
pthatcher1
2015/10/01 19:57:56
Again, can this be called CreateVoeChannel?
the sun
2015/10/13 15:07:03
Done.
| |
| 2123 void WebRtcVoiceMediaChannel::ConfigureSendChannel(int channel) { | 2100 int id = engine()->CreateVoiceChannel(); |
| 2124 if (engine()->voe()->network()->RegisterExternalTransport( | 2101 if (id == -1) { |
| 2125 channel, *this) == -1) { | 2102 LOG_RTCERR0(CreateVoiceChannel); |
| 2126 LOG_RTCERR2(RegisterExternalTransport, channel, this); | 2103 return -1; |
| 2127 } | 2104 } |
| 2128 | 2105 |
| 2129 // Enable RTCP (for quality stats and feedback messages) | 2106 if (engine()->voe()->network()->RegisterExternalTransport(id, *this) == -1) { |
| 2130 EnableRtcp(channel); | 2107 LOG_RTCERR2(RegisterExternalTransport, id, this); |
| 2131 | 2108 engine()->voe()->base()->DeleteChannel(id); |
| 2132 // Set RTP header extension for the new channel. | 2109 return -1; |
| 2133 SetChannelSendRtpHeaderExtensions(channel, send_extensions_); | 2110 } |
| 2111 return id; | |
| 2134 } | 2112 } |
| 2135 | 2113 |
| 2136 bool WebRtcVoiceMediaChannel::DeleteChannel(int channel) { | 2114 bool WebRtcVoiceMediaChannel::DeleteChannel(int channel) { |
| 2137 if (engine()->voe()->network()->DeRegisterExternalTransport(channel) == -1) { | 2115 if (engine()->voe()->network()->DeRegisterExternalTransport(channel) == -1) { |
| 2138 LOG_RTCERR1(DeRegisterExternalTransport, channel); | 2116 LOG_RTCERR1(DeRegisterExternalTransport, channel); |
| 2139 } | 2117 } |
| 2140 | |
| 2141 if (engine()->voe()->base()->DeleteChannel(channel) == -1) { | 2118 if (engine()->voe()->base()->DeleteChannel(channel) == -1) { |
| 2142 LOG_RTCERR1(DeleteChannel, channel); | 2119 LOG_RTCERR1(DeleteChannel, channel); |
| 2143 return false; | 2120 return false; |
| 2144 } | 2121 } |
| 2145 | |
| 2146 return true; | 2122 return true; |
| 2147 } | 2123 } |
| 2148 | 2124 |
| 2149 bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { | 2125 bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { |
| 2150 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2126 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 2151 // If the default channel is already used for sending create a new channel | 2127 uint32 ssrc = sp.first_ssrc(); |
| 2152 // otherwise use the default channel for sending. | 2128 RTC_DCHECK(0 != ssrc); |
| 2153 int channel = GetSendChannelNum(sp.first_ssrc()); | 2129 |
| 2154 if (channel != -1) { | 2130 if (-1 != GetSendChannelNum(ssrc)) { |
|
pthatcher1
2015/10/01 19:57:56
"-1 != X" here and "X == -1" below. Please be con
the sun
2015/10/13 15:07:03
Done.
| |
| 2155 LOG(LS_ERROR) << "Stream already exists with ssrc " << sp.first_ssrc(); | 2131 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; |
| 2156 return false; | 2132 return false; |
| 2157 } | 2133 } |
| 2158 | 2134 |
| 2159 bool default_channel_is_available = true; | 2135 // Create a new channel for sending audio data. |
| 2160 for (const auto& ch : send_channels_) { | 2136 int channel = CreateChannel(); |
| 2161 if (IsDefaultChannel(ch.second->channel())) { | 2137 if (channel == -1) { |
| 2162 default_channel_is_available = false; | 2138 return false; |
| 2163 break; | |
| 2164 } | |
| 2165 } | 2139 } |
| 2166 if (default_channel_is_available) { | |
| 2167 channel = voe_channel(); | |
| 2168 } else { | |
| 2169 // Create a new channel for sending audio data. | |
| 2170 channel = engine()->CreateMediaVoiceChannel(); | |
| 2171 if (channel == -1) { | |
| 2172 LOG_RTCERR0(CreateChannel); | |
| 2173 return false; | |
| 2174 } | |
| 2175 | 2140 |
| 2176 ConfigureSendChannel(channel); | 2141 // Enable RTCP (for quality stats and feedback messages). |
| 2142 if (engine()->voe()->rtp()->SetRTCPStatus(channel, true) == -1) { | |
| 2143 LOG_RTCERR2(SetRTCPStatus, channel, 1); | |
| 2144 } | |
| 2145 | |
| 2146 SetChannelSendRtpHeaderExtensions(channel, send_extensions_); | |
| 2147 | |
| 2148 // Set the send (local) SSRC. | |
| 2149 // If there are multiple send SSRCs, we can only set the first one here, and | |
| 2150 // the rest of the SSRC(s) need to be set after SetSendCodec has been called | |
| 2151 // (with a codec requires multiple SSRC(s)). | |
|
pthatcher1
2015/10/01 19:57:56
What does "with a codec requires multiple SSRC(s)"
the sun
2015/10/13 15:07:03
We don't support any audio codecs that require mul
| |
| 2152 if (engine()->voe()->rtp()->SetLocalSSRC(channel, ssrc) == -1) { | |
| 2153 LOG_RTCERR2(SetSendSSRC, channel, ssrc); | |
| 2154 DeleteChannel(channel); | |
| 2155 return false; | |
| 2156 } | |
| 2157 | |
| 2158 if (engine()->voe()->rtp()->SetRTCP_CNAME(channel, sp.cname.c_str()) == -1) { | |
| 2159 LOG_RTCERR2(SetRTCP_CNAME, channel, sp.cname); | |
| 2160 DeleteChannel(channel); | |
| 2161 return false; | |
| 2162 } | |
| 2163 | |
| 2164 // Set the current codecs to be used for the new channel. | |
| 2165 if (!send_codecs_.empty() && !SetSendCodecs(channel, send_codecs_)) { | |
| 2166 DeleteChannel(channel); | |
| 2167 return false; | |
| 2177 } | 2168 } |
| 2178 | 2169 |
| 2179 // Save the channel to send_channels_, so that RemoveSendStream() can still | 2170 // Save the channel to send_channels_, so that RemoveSendStream() can still |
| 2180 // delete the channel in case failure happens below. | 2171 // delete the channel in case failure happens below. |
| 2181 webrtc::AudioTransport* audio_transport = | 2172 webrtc::AudioTransport* audio_transport = |
| 2182 engine()->voe()->base()->audio_transport(); | 2173 engine()->voe()->base()->audio_transport(); |
| 2183 send_channels_.insert( | 2174 send_channels_.insert( |
| 2184 std::make_pair(sp.first_ssrc(), | 2175 std::make_pair(ssrc, |
| 2185 new WebRtcVoiceChannelRenderer(channel, audio_transport))); | 2176 new WebRtcVoiceChannelRenderer(channel, audio_transport))); |
| 2186 | 2177 |
| 2187 // Set the send (local) SSRC. | |
| 2188 // If there are multiple send SSRCs, we can only set the first one here, and | |
| 2189 // the rest of the SSRC(s) need to be set after SetSendCodec has been called | |
| 2190 // (with a codec requires multiple SSRC(s)). | |
| 2191 if (engine()->voe()->rtp()->SetLocalSSRC(channel, sp.first_ssrc()) == -1) { | |
| 2192 LOG_RTCERR2(SetSendSSRC, channel, sp.first_ssrc()); | |
| 2193 return false; | |
| 2194 } | |
| 2195 | |
| 2196 // At this point the channel's local SSRC has been updated. If the channel is | 2178 // At this point the channel's local SSRC has been updated. If the channel is |
| 2197 // the default channel make sure that all the receive channels are updated as | 2179 // the first send channel make sure that all the receive channels are updated |
| 2198 // well. Receive channels have to have the same SSRC as the default channel in | 2180 // with the same SSRC in order to send receiver reports. |
| 2199 // order to send receiver reports with this SSRC. | 2181 if (send_channels_.size() == 1) { |
| 2200 if (IsDefaultChannel(channel)) { | |
| 2201 for (const auto& ch : receive_channels_) { | 2182 for (const auto& ch : receive_channels_) { |
| 2202 if (engine()->voe()->rtp()->SetLocalSSRC(ch.second->channel(), | 2183 int recv_channel = ch.second->channel(); |
| 2203 sp.first_ssrc()) != 0) { | 2184 if (engine()->voe()->rtp()->SetLocalSSRC(recv_channel, ssrc) != 0) { |
| 2204 LOG_RTCERR2(SetLocalSSRC, ch.second->channel(), sp.first_ssrc()); | 2185 LOG_RTCERR2(SetLocalSSRC, ch.second->channel(), ssrc); |
| 2205 return false; | 2186 return false; |
| 2206 } | 2187 } |
| 2188 engine()->voe()->base()->AssociateSendChannel(recv_channel, channel); | |
| 2189 LOG(LS_INFO) << "VoiceEngine channel #" << recv_channel | |
| 2190 << " is associated with channel #" << channel << "."; | |
| 2207 } | 2191 } |
| 2208 } | 2192 } |
| 2209 | 2193 |
| 2210 if (engine()->voe()->rtp()->SetRTCP_CNAME(channel, sp.cname.c_str()) == -1) { | |
| 2211 LOG_RTCERR2(SetRTCP_CNAME, channel, sp.cname); | |
| 2212 return false; | |
| 2213 } | |
| 2214 | |
| 2215 // Set the current codecs to be used for the new channel. | |
| 2216 if (!send_codecs_.empty() && !SetSendCodecs(channel, send_codecs_)) | |
| 2217 return false; | |
| 2218 | |
| 2219 return ChangeSend(channel, desired_send_); | 2194 return ChangeSend(channel, desired_send_); |
| 2220 } | 2195 } |
| 2221 | 2196 |
| 2222 bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32 ssrc) { | 2197 bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32 ssrc) { |
| 2198 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
| 2223 ChannelMap::iterator it = send_channels_.find(ssrc); | 2199 ChannelMap::iterator it = send_channels_.find(ssrc); |
| 2224 if (it == send_channels_.end()) { | 2200 if (it == send_channels_.end()) { |
| 2225 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc | 2201 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc |
| 2226 << " which doesn't exist."; | 2202 << " which doesn't exist."; |
| 2227 return false; | 2203 return false; |
| 2228 } | 2204 } |
| 2229 | 2205 |
| 2230 int channel = it->second->channel(); | 2206 int channel = it->second->channel(); |
| 2231 ChangeSend(channel, SEND_NOTHING); | 2207 ChangeSend(channel, SEND_NOTHING); |
| 2232 | 2208 |
| 2233 // Delete the WebRtcVoiceChannelRenderer object connected to the channel, | 2209 // Delete the WebRtcVoiceChannelRenderer object connected to the channel, |
| 2234 // this will disconnect the audio renderer with the send channel. | 2210 // this will disconnect the audio renderer with the send channel. |
| 2235 delete it->second; | 2211 delete it->second; |
| 2236 send_channels_.erase(it); | 2212 send_channels_.erase(it); |
| 2237 | 2213 |
| 2238 if (IsDefaultChannel(channel)) { | 2214 // Clean up and delete the send channel. |
| 2239 // Do not delete the default channel since the receive channels depend on | 2215 LOG(LS_INFO) << "Removing audio send stream " << ssrc |
| 2240 // the default channel, recycle it instead. | 2216 << " with VoiceEngine channel #" << channel << "."; |
| 2241 ChangeSend(channel, SEND_NOTHING); | 2217 if (!DeleteChannel(channel)) { |
| 2242 } else { | 2218 return false; |
| 2243 // Clean up and delete the send channel. | |
| 2244 LOG(LS_INFO) << "Removing audio send stream " << ssrc | |
| 2245 << " with VoiceEngine channel #" << channel << "."; | |
| 2246 if (!DeleteChannel(channel)) | |
| 2247 return false; | |
| 2248 } | 2219 } |
| 2249 | 2220 if (send_channels_.empty()) { |
| 2250 if (send_channels_.empty()) | |
| 2251 ChangeSend(SEND_NOTHING); | 2221 ChangeSend(SEND_NOTHING); |
| 2252 | 2222 } |
| 2253 return true; | 2223 return true; |
| 2254 } | 2224 } |
| 2255 | 2225 |
| 2256 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { | 2226 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { |
| 2257 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2227 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 2258 LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); | 2228 LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); |
| 2259 | 2229 |
| 2260 if (!ValidateStreamParams(sp)) { | 2230 if (!ValidateStreamParams(sp)) { |
| 2261 return false; | 2231 return false; |
| 2262 } | 2232 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2273 RemoveRecvStream(ssrc); | 2243 RemoveRecvStream(ssrc); |
| 2274 } | 2244 } |
| 2275 | 2245 |
| 2276 if (receive_channels_.find(ssrc) != receive_channels_.end()) { | 2246 if (receive_channels_.find(ssrc) != receive_channels_.end()) { |
| 2277 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; | 2247 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; |
| 2278 return false; | 2248 return false; |
| 2279 } | 2249 } |
| 2280 RTC_DCHECK(receive_stream_params_.find(ssrc) == receive_stream_params_.end()); | 2250 RTC_DCHECK(receive_stream_params_.find(ssrc) == receive_stream_params_.end()); |
| 2281 | 2251 |
| 2282 // Create a new channel for receiving audio data. | 2252 // Create a new channel for receiving audio data. |
| 2283 int channel = engine()->CreateMediaVoiceChannel(); | 2253 int channel = CreateChannel(); |
| 2284 if (channel == -1) { | 2254 if (channel == -1) { |
| 2285 LOG_RTCERR0(CreateChannel); | |
| 2286 return false; | 2255 return false; |
| 2287 } | 2256 } |
| 2288 if (!ConfigureRecvChannel(channel)) { | 2257 if (!ConfigureRecvChannel(channel)) { |
| 2289 DeleteChannel(channel); | 2258 DeleteChannel(channel); |
| 2290 return false; | 2259 return false; |
| 2291 } | 2260 } |
| 2292 | 2261 |
| 2293 webrtc::AudioTransport* audio_transport = | 2262 webrtc::AudioTransport* audio_transport = |
| 2294 engine()->voe()->base()->audio_transport(); | 2263 engine()->voe()->base()->audio_transport(); |
| 2295 WebRtcVoiceChannelRenderer* channel_renderer = | 2264 WebRtcVoiceChannelRenderer* channel_renderer = |
| 2296 new WebRtcVoiceChannelRenderer(channel, audio_transport); | 2265 new WebRtcVoiceChannelRenderer(channel, audio_transport); |
| 2297 receive_channels_.insert(std::make_pair(ssrc, channel_renderer)); | 2266 receive_channels_.insert(std::make_pair(ssrc, channel_renderer)); |
| 2298 receive_stream_params_[ssrc] = sp; | 2267 receive_stream_params_[ssrc] = sp; |
| 2299 AddAudioReceiveStream(ssrc); | 2268 AddAudioReceiveStream(ssrc); |
| 2300 | 2269 |
| 2301 LOG(LS_INFO) << "New audio stream " << ssrc | 2270 LOG(LS_INFO) << "New audio stream " << ssrc |
| 2302 << " registered to VoiceEngine channel #" | 2271 << " registered to VoiceEngine channel #" |
| 2303 << channel << "."; | 2272 << channel << "."; |
| 2304 return true; | 2273 return true; |
| 2305 } | 2274 } |
| 2306 | 2275 |
| 2307 bool WebRtcVoiceMediaChannel::ConfigureRecvChannel(int channel) { | 2276 bool WebRtcVoiceMediaChannel::ConfigureRecvChannel(int channel) { |
| 2308 // Configure to use external transport. | |
| 2309 if (engine()->voe()->network()->RegisterExternalTransport( | |
| 2310 channel, *this) == -1) { | |
| 2311 LOG_RTCERR2(SetExternalTransport, channel, this); | |
| 2312 return false; | |
| 2313 } | |
| 2314 | |
| 2315 if (!SetRecvOptions(channel)) { | 2277 if (!SetRecvOptions(channel)) { |
| 2316 return false; | 2278 return false; |
| 2317 } | 2279 } |
| 2318 | 2280 |
| 2319 // Use the same SSRC as our default (send) channel, so the RTCP reports are | 2281 uint32 rtcp_ssrc = kDefaultRtcpReceiverReportSsrc; |
| 2320 // correct. | 2282 if (send_channels_.size() > 0) { |
| 2321 unsigned int send_ssrc = 0; | 2283 rtcp_ssrc = send_channels_.begin()->first; |
| 2322 webrtc::VoERTP_RTCP* rtp = engine()->voe()->rtp(); | 2284 |
| 2323 if (rtp->GetLocalSSRC(voe_channel(), send_ssrc) == -1) { | 2285 // Associate receive channel to default send channel (so the receive channel |
| 2324 LOG_RTCERR1(GetSendSSRC, channel); | 2286 // can obtain RTT from the send channel) |
| 2287 int send_channel = send_channels_.begin()->second->channel(); | |
| 2288 engine()->voe()->base()->AssociateSendChannel(channel, send_channel); | |
| 2289 LOG(LS_INFO) << "VoiceEngine channel #" << channel | |
| 2290 << " is associated with channel #" << send_channel << "."; | |
| 2291 } | |
| 2292 if (engine()->voe()->rtp()->SetLocalSSRC(channel, rtcp_ssrc) == -1) { | |
| 2293 LOG_RTCERR1(SetLocalSSRC, channel); | |
| 2325 return false; | 2294 return false; |
| 2326 } | 2295 } |
| 2327 if (rtp->SetLocalSSRC(channel, send_ssrc) == -1) { | |
| 2328 LOG_RTCERR1(SetSendSSRC, channel); | |
| 2329 return false; | |
| 2330 } | |
| 2331 | |
| 2332 // Associate receive channel to default send channel (so the receive channel | |
| 2333 // can obtain RTT from the send channel) | |
| 2334 engine()->voe()->base()->AssociateSendChannel(channel, voe_channel()); | |
| 2335 LOG(LS_INFO) << "VoiceEngine channel #" | |
| 2336 << channel << " is associated with channel #" | |
| 2337 << voe_channel() << "."; | |
| 2338 | 2296 |
| 2339 // Turn off all supported codecs. | 2297 // Turn off all supported codecs. |
| 2340 int ncodecs = engine()->voe()->codec()->NumOfCodecs(); | 2298 int ncodecs = engine()->voe()->codec()->NumOfCodecs(); |
| 2341 for (int i = 0; i < ncodecs; ++i) { | 2299 for (int i = 0; i < ncodecs; ++i) { |
| 2342 webrtc::CodecInst voe_codec; | 2300 webrtc::CodecInst voe_codec; |
| 2343 if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) { | 2301 if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) { |
| 2344 voe_codec.pltype = -1; | 2302 voe_codec.pltype = -1; |
| 2345 if (engine()->voe()->codec()->SetRecPayloadType( | 2303 if (engine()->voe()->codec()->SetRecPayloadType( |
| 2346 channel, voe_codec) == -1) { | 2304 channel, voe_codec) == -1) { |
| 2347 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); | 2305 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2538 } | 2496 } |
| 2539 return true; | 2497 return true; |
| 2540 } | 2498 } |
| 2541 | 2499 |
| 2542 bool WebRtcVoiceMediaChannel::CanInsertDtmf() { | 2500 bool WebRtcVoiceMediaChannel::CanInsertDtmf() { |
| 2543 return dtmf_allowed_; | 2501 return dtmf_allowed_; |
| 2544 } | 2502 } |
| 2545 | 2503 |
| 2546 bool WebRtcVoiceMediaChannel::InsertDtmf(uint32 ssrc, int event, | 2504 bool WebRtcVoiceMediaChannel::InsertDtmf(uint32 ssrc, int event, |
| 2547 int duration, int flags) { | 2505 int duration, int flags) { |
| 2506 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
| 2548 if (!dtmf_allowed_) { | 2507 if (!dtmf_allowed_) { |
| 2549 return false; | 2508 return false; |
| 2550 } | 2509 } |
| 2551 | 2510 |
| 2552 // Send the event. | 2511 // Send the event. |
| 2553 if (flags & cricket::DF_SEND) { | 2512 if (flags & cricket::DF_SEND) { |
| 2554 int channel = -1; | 2513 int channel = -1; |
| 2555 if (ssrc == 0) { | 2514 if (ssrc == 0) { |
| 2556 bool default_channel_is_inuse = false; | 2515 if (send_channels_.size() > 0) { |
| 2557 for (const auto& ch : send_channels_) { | |
| 2558 if (IsDefaultChannel(ch.second->channel())) { | |
| 2559 default_channel_is_inuse = true; | |
| 2560 break; | |
| 2561 } | |
| 2562 } | |
| 2563 if (default_channel_is_inuse) { | |
| 2564 channel = voe_channel(); | |
| 2565 } else if (!send_channels_.empty()) { | |
| 2566 channel = send_channels_.begin()->second->channel(); | 2516 channel = send_channels_.begin()->second->channel(); |
| 2567 } | 2517 } |
| 2568 } else { | 2518 } else { |
| 2569 channel = GetSendChannelNum(ssrc); | 2519 channel = GetSendChannelNum(ssrc); |
| 2570 } | 2520 } |
| 2571 if (channel == -1) { | 2521 if (channel == -1) { |
| 2572 LOG(LS_WARNING) << "InsertDtmf - The specified ssrc " | 2522 LOG(LS_WARNING) << "InsertDtmf - The specified ssrc " |
| 2573 << ssrc << " is not in use."; | 2523 << ssrc << " is not in use."; |
| 2574 return false; | 2524 return false; |
| 2575 } | 2525 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2674 // SR may continue RR and any RR entry may correspond to any one of the send | 2624 // SR may continue RR and any RR entry may correspond to any one of the send |
| 2675 // channels. So all RTCP packets must be forwarded all send channels. VoE | 2625 // channels. So all RTCP packets must be forwarded all send channels. VoE |
| 2676 // will filter out RR internally. | 2626 // will filter out RR internally. |
| 2677 for (const auto& ch : send_channels_) { | 2627 for (const auto& ch : send_channels_) { |
| 2678 engine()->voe()->network()->ReceivedRTCPPacket( | 2628 engine()->voe()->network()->ReceivedRTCPPacket( |
| 2679 ch.second->channel(), packet->data(), packet->size()); | 2629 ch.second->channel(), packet->data(), packet->size()); |
| 2680 } | 2630 } |
| 2681 } | 2631 } |
| 2682 | 2632 |
| 2683 bool WebRtcVoiceMediaChannel::MuteStream(uint32 ssrc, bool muted) { | 2633 bool WebRtcVoiceMediaChannel::MuteStream(uint32 ssrc, bool muted) { |
| 2684 int channel = (ssrc == 0) ? voe_channel() : GetSendChannelNum(ssrc); | 2634 int channel = -1; |
| 2635 if (ssrc == 0) { | |
| 2636 if (send_channels_.size() > 0) { | |
| 2637 channel = send_channels_.begin()->second->channel(); | |
| 2638 } | |
|
pthatcher1
2015/10/01 19:57:56
The only thing that ever used ssrc=0 here was GTP,
the sun
2015/10/13 15:07:03
Done.
| |
| 2639 } else { | |
| 2640 channel = GetSendChannelNum(ssrc); | |
| 2641 } | |
| 2685 if (channel == -1) { | 2642 if (channel == -1) { |
| 2686 LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use."; | 2643 LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use."; |
| 2687 return false; | 2644 return false; |
| 2688 } | 2645 } |
| 2689 if (engine()->voe()->volume()->SetInputMute(channel, muted) == -1) { | 2646 if (engine()->voe()->volume()->SetInputMute(channel, muted) == -1) { |
| 2690 LOG_RTCERR2(SetInputMute, channel, muted); | 2647 LOG_RTCERR2(SetInputMute, channel, muted); |
| 2691 return false; | 2648 return false; |
| 2692 } | 2649 } |
| 2693 // We set the AGC to mute state only when all the channels are muted. | 2650 // We set the AGC to mute state only when all the channels are muted. |
| 2694 // This implementation is not ideal, instead we should signal the AGC when | 2651 // This implementation is not ideal, instead we should signal the AGC when |
| 2695 // the mic channel is muted/unmuted. We can't do it today because there | 2652 // the mic channel is muted/unmuted. We can't do it today because there |
| 2696 // is no good way to know which stream is mapping to the mic channel. | 2653 // is no good way to know which stream is mapping to the mic channel. |
| 2697 bool all_muted = muted; | 2654 bool all_muted = muted; |
| 2698 for (const auto& ch : send_channels_) { | 2655 for (const auto& ch : send_channels_) { |
| 2699 if (!all_muted) { | 2656 if (!all_muted) { |
| 2700 break; | 2657 break; |
| 2701 } | 2658 } |
| 2702 if (engine()->voe()->volume()->GetInputMute(ch.second->channel(), | 2659 if (engine()->voe()->volume()->GetInputMute(ch.second->channel(), |
| 2703 all_muted)) { | 2660 all_muted)) { |
| 2704 LOG_RTCERR1(GetInputMute, ch.second->channel()); | 2661 LOG_RTCERR1(GetInputMute, ch.second->channel()); |
| 2705 return false; | 2662 return false; |
| 2706 } | 2663 } |
| 2707 } | 2664 } |
| 2708 | 2665 |
| 2709 webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing(); | 2666 webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing(); |
| 2710 if (ap) | 2667 if (ap) { |
| 2711 ap->set_output_will_be_muted(all_muted); | 2668 ap->set_output_will_be_muted(all_muted); |
| 2669 } | |
| 2712 return true; | 2670 return true; |
| 2713 } | 2671 } |
| 2714 | 2672 |
| 2715 // TODO(minyue): SetMaxSendBandwidth() is subject to be renamed to | 2673 // TODO(minyue): SetMaxSendBandwidth() is subject to be renamed to |
| 2716 // SetMaxSendBitrate() in future. | 2674 // SetMaxSendBitrate() in future. |
| 2717 bool WebRtcVoiceMediaChannel::SetMaxSendBandwidth(int bps) { | 2675 bool WebRtcVoiceMediaChannel::SetMaxSendBandwidth(int bps) { |
| 2718 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetMaxSendBandwidth."; | 2676 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetMaxSendBandwidth."; |
| 2719 | |
| 2720 return SetSendBitrateInternal(bps); | 2677 return SetSendBitrateInternal(bps); |
| 2721 } | 2678 } |
| 2722 | 2679 |
| 2723 bool WebRtcVoiceMediaChannel::SetSendBitrateInternal(int bps) { | 2680 bool WebRtcVoiceMediaChannel::SetSendBitrateInternal(int bps) { |
| 2724 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetSendBitrateInternal."; | 2681 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetSendBitrateInternal."; |
| 2725 | 2682 |
| 2726 send_bitrate_setting_ = true; | 2683 send_bitrate_setting_ = true; |
| 2727 send_bitrate_bps_ = bps; | 2684 send_bitrate_bps_ = bps; |
| 2728 | 2685 |
| 2729 if (!send_codec_) { | 2686 if (!send_codec_) { |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2990 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { | 2947 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { |
| 2991 unsigned int ulevel; | 2948 unsigned int ulevel; |
| 2992 int ret = | 2949 int ret = |
| 2993 engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); | 2950 engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); |
| 2994 return (ret == 0) ? static_cast<int>(ulevel) : -1; | 2951 return (ret == 0) ? static_cast<int>(ulevel) : -1; |
| 2995 } | 2952 } |
| 2996 | 2953 |
| 2997 int WebRtcVoiceMediaChannel::GetReceiveChannelNum(uint32 ssrc) const { | 2954 int WebRtcVoiceMediaChannel::GetReceiveChannelNum(uint32 ssrc) const { |
| 2998 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2955 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 2999 ChannelMap::const_iterator it = receive_channels_.find(ssrc); | 2956 ChannelMap::const_iterator it = receive_channels_.find(ssrc); |
| 3000 if (it != receive_channels_.end()) | 2957 if (it != receive_channels_.end()) { |
| 3001 return it->second->channel(); | 2958 return it->second->channel(); |
| 2959 } | |
| 3002 return -1; | 2960 return -1; |
| 3003 } | 2961 } |
| 3004 | 2962 |
| 3005 int WebRtcVoiceMediaChannel::GetSendChannelNum(uint32 ssrc) const { | 2963 int WebRtcVoiceMediaChannel::GetSendChannelNum(uint32 ssrc) const { |
|
pthatcher1
2015/10/01 19:57:56
Can you rename this to GetSendChannelBySsrc?
the sun
2015/10/13 15:07:03
Not going to do that right now.
| |
| 2964 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
| 3006 ChannelMap::const_iterator it = send_channels_.find(ssrc); | 2965 ChannelMap::const_iterator it = send_channels_.find(ssrc); |
| 3007 if (it != send_channels_.end()) | 2966 if (it != send_channels_.end()) { |
| 3008 return it->second->channel(); | 2967 return it->second->channel(); |
| 2968 } | |
| 3009 return -1; | 2969 return -1; |
| 3010 } | 2970 } |
| 3011 | 2971 |
| 3012 bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec, | 2972 bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec, |
| 3013 const std::vector<AudioCodec>& all_codecs, webrtc::CodecInst* send_codec) { | 2973 const std::vector<AudioCodec>& all_codecs, webrtc::CodecInst* send_codec) { |
| 3014 // Get the RED encodings from the parameter with no name. This may | 2974 // Get the RED encodings from the parameter with no name. This may |
| 3015 // change based on what is discussed on the Jingle list. | 2975 // change based on what is discussed on the Jingle list. |
| 3016 // The encoding parameter is of the form "a/b"; we only support where | 2976 // The encoding parameter is of the form "a/b"; we only support where |
| 3017 // a == b. Verify this and parse out the value into red_pt. | 2977 // a == b. Verify this and parse out the value into red_pt. |
| 3018 // If the parameter value is absent (as it will be until we wire up the | 2978 // If the parameter value is absent (as it will be until we wire up the |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 3046 return true; | 3006 return true; |
| 3047 } else { | 3007 } else { |
| 3048 break; | 3008 break; |
| 3049 } | 3009 } |
| 3050 } | 3010 } |
| 3051 } | 3011 } |
| 3052 LOG(LS_WARNING) << "RED params " << red_params << " are invalid."; | 3012 LOG(LS_WARNING) << "RED params " << red_params << " are invalid."; |
| 3053 return false; | 3013 return false; |
| 3054 } | 3014 } |
| 3055 | 3015 |
| 3056 bool WebRtcVoiceMediaChannel::EnableRtcp(int channel) { | |
| 3057 if (engine()->voe()->rtp()->SetRTCPStatus(channel, true) == -1) { | |
| 3058 LOG_RTCERR2(SetRTCPStatus, channel, 1); | |
| 3059 return false; | |
| 3060 } | |
| 3061 // TODO(juberti): Enable VQMon and RTCP XR reports, once we know what | |
| 3062 // what we want to do with them. | |
| 3063 // engine()->voe().EnableVQMon(voe_channel(), true); | |
| 3064 // engine()->voe().EnableRTCP_XR(voe_channel(), true); | |
| 3065 return true; | |
| 3066 } | |
| 3067 | |
| 3068 bool WebRtcVoiceMediaChannel::SetPlayout(int channel, bool playout) { | 3016 bool WebRtcVoiceMediaChannel::SetPlayout(int channel, bool playout) { |
| 3069 if (playout) { | 3017 if (playout) { |
| 3070 LOG(LS_INFO) << "Starting playout for channel #" << channel; | 3018 LOG(LS_INFO) << "Starting playout for channel #" << channel; |
| 3071 if (engine()->voe()->base()->StartPlayout(channel) == -1) { | 3019 if (engine()->voe()->base()->StartPlayout(channel) == -1) { |
| 3072 LOG_RTCERR1(StartPlayout, channel); | 3020 LOG_RTCERR1(StartPlayout, channel); |
| 3073 return false; | 3021 return false; |
| 3074 } | 3022 } |
| 3075 } else { | 3023 } else { |
| 3076 LOG(LS_INFO) << "Stopping playout for channel #" << channel; | 3024 LOG(LS_INFO) << "Stopping playout for channel #" << channel; |
| 3077 engine()->voe()->base()->StopPlayout(channel); | 3025 engine()->voe()->base()->StopPlayout(channel); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3185 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | 3133 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); |
| 3186 return false; | 3134 return false; |
| 3187 } | 3135 } |
| 3188 } | 3136 } |
| 3189 return true; | 3137 return true; |
| 3190 } | 3138 } |
| 3191 | 3139 |
| 3192 } // namespace cricket | 3140 } // namespace cricket |
| 3193 | 3141 |
| 3194 #endif // HAVE_WEBRTC_VOICE | 3142 #endif // HAVE_WEBRTC_VOICE |
| OLD | NEW |