| 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 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 } | 386 } |
| 387 | 387 |
| 388 std::string GetEnableString(bool enable) { | 388 std::string GetEnableString(bool enable) { |
| 389 return enable ? "enable" : "disable"; | 389 return enable ? "enable" : "disable"; |
| 390 } | 390 } |
| 391 } // namespace { | 391 } // namespace { |
| 392 | 392 |
| 393 WebRtcVoiceEngine::WebRtcVoiceEngine() | 393 WebRtcVoiceEngine::WebRtcVoiceEngine() |
| 394 : voe_wrapper_(new VoEWrapper()), | 394 : voe_wrapper_(new VoEWrapper()), |
| 395 tracing_(new VoETraceWrapper()), | 395 tracing_(new VoETraceWrapper()), |
| 396 adm_(NULL), | 396 log_filter_(SeverityToFilter(kDefaultLogSeverity)) { |
| 397 log_filter_(SeverityToFilter(kDefaultLogSeverity)), | |
| 398 is_dumping_aec_(false) { | |
| 399 Construct(); | 397 Construct(); |
| 400 } | 398 } |
| 401 | 399 |
| 402 WebRtcVoiceEngine::WebRtcVoiceEngine(VoEWrapper* voe_wrapper, | 400 WebRtcVoiceEngine::WebRtcVoiceEngine(VoEWrapper* voe_wrapper, |
| 403 VoETraceWrapper* tracing) | 401 VoETraceWrapper* tracing) |
| 404 : voe_wrapper_(voe_wrapper), | 402 : voe_wrapper_(voe_wrapper), |
| 405 tracing_(tracing), | 403 tracing_(tracing), |
| 406 adm_(NULL), | 404 log_filter_(SeverityToFilter(kDefaultLogSeverity)) { |
| 407 log_filter_(SeverityToFilter(kDefaultLogSeverity)), | |
| 408 is_dumping_aec_(false) { | |
| 409 Construct(); | 405 Construct(); |
| 410 } | 406 } |
| 411 | 407 |
| 412 void WebRtcVoiceEngine::Construct() { | 408 void WebRtcVoiceEngine::Construct() { |
| 413 SetTraceFilter(log_filter_); | 409 SetTraceFilter(log_filter_); |
| 414 initialized_ = false; | |
| 415 LOG(LS_VERBOSE) << "WebRtcVoiceEngine::WebRtcVoiceEngine"; | 410 LOG(LS_VERBOSE) << "WebRtcVoiceEngine::WebRtcVoiceEngine"; |
| 416 SetTraceOptions(""); | 411 SetTraceOptions(""); |
| 417 if (tracing_->SetTraceCallback(this) == -1) { | 412 if (tracing_->SetTraceCallback(this) == -1) { |
| 418 LOG_RTCERR0(SetTraceCallback); | 413 LOG_RTCERR0(SetTraceCallback); |
| 419 } | 414 } |
| 420 if (voe_wrapper_->base()->RegisterVoiceEngineObserver(*this) == -1) { | |
| 421 LOG_RTCERR0(RegisterVoiceEngineObserver); | |
| 422 } | |
| 423 // Clear the default agc state. | |
| 424 memset(&default_agc_config_, 0, sizeof(default_agc_config_)); | |
| 425 | 415 |
| 426 // Load our audio codec list. | 416 // Load our audio codec list. |
| 427 ConstructCodecs(); | 417 ConstructCodecs(); |
| 428 | 418 |
| 429 // Load our RTP Header extensions. | 419 // Load our RTP Header extensions. |
| 430 rtp_header_extensions_.push_back( | 420 rtp_header_extensions_.push_back( |
| 431 RtpHeaderExtension(kRtpAudioLevelHeaderExtension, | 421 RtpHeaderExtension(kRtpAudioLevelHeaderExtension, |
| 432 kRtpAudioLevelHeaderExtensionDefaultId)); | 422 kRtpAudioLevelHeaderExtensionDefaultId)); |
| 433 rtp_header_extensions_.push_back( | 423 rtp_header_extensions_.push_back( |
| 434 RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, | 424 RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 if (voe_wrapper_->codec()->GetCodec(index, *codec) == -1) { | 492 if (voe_wrapper_->codec()->GetCodec(index, *codec) == -1) { |
| 503 return false; | 493 return false; |
| 504 } | 494 } |
| 505 // Change the sample rate of G722 to 8000 to match SDP. | 495 // Change the sample rate of G722 to 8000 to match SDP. |
| 506 MaybeFixupG722(codec, 8000); | 496 MaybeFixupG722(codec, 8000); |
| 507 return true; | 497 return true; |
| 508 } | 498 } |
| 509 | 499 |
| 510 WebRtcVoiceEngine::~WebRtcVoiceEngine() { | 500 WebRtcVoiceEngine::~WebRtcVoiceEngine() { |
| 511 LOG(LS_VERBOSE) << "WebRtcVoiceEngine::~WebRtcVoiceEngine"; | 501 LOG(LS_VERBOSE) << "WebRtcVoiceEngine::~WebRtcVoiceEngine"; |
| 512 if (voe_wrapper_->base()->DeRegisterVoiceEngineObserver() == -1) { | |
| 513 LOG_RTCERR0(DeRegisterVoiceEngineObserver); | |
| 514 } | |
| 515 if (adm_) { | 502 if (adm_) { |
| 516 voe_wrapper_.reset(); | 503 voe_wrapper_.reset(); |
| 517 adm_->Release(); | 504 adm_->Release(); |
| 518 adm_ = NULL; | 505 adm_ = NULL; |
| 519 } | 506 } |
| 520 | 507 |
| 521 tracing_->SetTraceCallback(NULL); | 508 tracing_->SetTraceCallback(NULL); |
| 522 } | 509 } |
| 523 | 510 |
| 524 bool WebRtcVoiceEngine::Init(rtc::Thread* worker_thread) { | 511 bool WebRtcVoiceEngine::Init(rtc::Thread* worker_thread) { |
| (...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1194 if (length < 72) { | 1181 if (length < 72) { |
| 1195 std::string msg(trace, length); | 1182 std::string msg(trace, length); |
| 1196 LOG(LS_ERROR) << "Malformed webrtc log message: "; | 1183 LOG(LS_ERROR) << "Malformed webrtc log message: "; |
| 1197 LOG_V(sev) << msg; | 1184 LOG_V(sev) << msg; |
| 1198 } else { | 1185 } else { |
| 1199 std::string msg(trace + 71, length - 72); | 1186 std::string msg(trace + 71, length - 72); |
| 1200 LOG_V(sev) << "webrtc: " << msg; | 1187 LOG_V(sev) << "webrtc: " << msg; |
| 1201 } | 1188 } |
| 1202 } | 1189 } |
| 1203 | 1190 |
| 1204 void WebRtcVoiceEngine::CallbackOnError(int channel_id, int err_code) { | |
| 1205 RTC_DCHECK(channel_id == -1); | |
| 1206 LOG(LS_WARNING) << "VoiceEngine error " << err_code << " reported on channel " | |
| 1207 << channel_id << "."; | |
| 1208 rtc::CritScope lock(&channels_cs_); | |
| 1209 for (WebRtcVoiceMediaChannel* channel : channels_) { | |
| 1210 channel->OnError(err_code); | |
| 1211 } | |
| 1212 } | |
| 1213 | |
| 1214 void WebRtcVoiceEngine::RegisterChannel(WebRtcVoiceMediaChannel* channel) { | 1191 void WebRtcVoiceEngine::RegisterChannel(WebRtcVoiceMediaChannel* channel) { |
| 1215 RTC_DCHECK(channel != NULL); | 1192 RTC_DCHECK(channel); |
| 1216 rtc::CritScope lock(&channels_cs_); | |
| 1217 channels_.push_back(channel); | 1193 channels_.push_back(channel); |
| 1218 } | 1194 } |
| 1219 | 1195 |
| 1220 void WebRtcVoiceEngine::UnregisterChannel(WebRtcVoiceMediaChannel* channel) { | 1196 void WebRtcVoiceEngine::UnregisterChannel(WebRtcVoiceMediaChannel* channel) { |
| 1221 rtc::CritScope lock(&channels_cs_); | |
| 1222 auto it = std::find(channels_.begin(), channels_.end(), channel); | 1197 auto it = std::find(channels_.begin(), channels_.end(), channel); |
| 1223 if (it != channels_.end()) { | 1198 RTC_DCHECK(it != channels_.end()); |
| 1224 channels_.erase(it); | 1199 channels_.erase(it); |
| 1225 } | |
| 1226 } | 1200 } |
| 1227 | 1201 |
| 1228 // Adjusts the default AGC target level by the specified delta. | 1202 // Adjusts the default AGC target level by the specified delta. |
| 1229 // NB: If we start messing with other config fields, we'll want | 1203 // NB: If we start messing with other config fields, we'll want |
| 1230 // to save the current webrtc::AgcConfig as well. | 1204 // to save the current webrtc::AgcConfig as well. |
| 1231 bool WebRtcVoiceEngine::AdjustAgcLevel(int delta) { | 1205 bool WebRtcVoiceEngine::AdjustAgcLevel(int delta) { |
| 1232 webrtc::AgcConfig config = default_agc_config_; | 1206 webrtc::AgcConfig config = default_agc_config_; |
| 1233 config.targetLeveldBOv -= delta; | 1207 config.targetLeveldBOv -= delta; |
| 1234 | 1208 |
| 1235 LOG(LS_INFO) << "Adjusting AGC level from default -" | 1209 LOG(LS_INFO) << "Adjusting AGC level from default -" |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1427 private: | 1401 private: |
| 1428 int channel_; | 1402 int channel_; |
| 1429 | 1403 |
| 1430 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioReceiveStream); | 1404 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioReceiveStream); |
| 1431 }; | 1405 }; |
| 1432 | 1406 |
| 1433 // WebRtcVoiceMediaChannel | 1407 // WebRtcVoiceMediaChannel |
| 1434 WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine, | 1408 WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine, |
| 1435 const AudioOptions& options, | 1409 const AudioOptions& options, |
| 1436 webrtc::Call* call) | 1410 webrtc::Call* call) |
| 1437 : engine_(engine), | 1411 : engine_(engine), call_(call) { |
| 1438 send_bitrate_setting_(false), | |
| 1439 send_bitrate_bps_(0), | |
| 1440 options_(), | |
| 1441 dtmf_allowed_(false), | |
| 1442 desired_playout_(false), | |
| 1443 nack_enabled_(false), | |
| 1444 playout_(false), | |
| 1445 typing_noise_detected_(false), | |
| 1446 desired_send_(SEND_NOTHING), | |
| 1447 send_(SEND_NOTHING), | |
| 1448 call_(call) { | |
| 1449 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel"; | 1412 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel"; |
| 1450 RTC_DCHECK(nullptr != call); | 1413 RTC_DCHECK(call); |
| 1451 engine->RegisterChannel(this); | 1414 engine->RegisterChannel(this); |
| 1452 SetOptions(options); | 1415 SetOptions(options); |
| 1453 } | 1416 } |
| 1454 | 1417 |
| 1455 WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() { | 1418 WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() { |
| 1456 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1419 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 1457 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel"; | 1420 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel"; |
| 1458 | 1421 |
| 1459 // Remove any remaining send streams. | 1422 // Remove any remaining send streams. |
| 1460 while (!send_streams_.empty()) { | 1423 while (!send_streams_.empty()) { |
| (...skipping 1184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2645 sinfo.codec_name = stats.codec_name; | 2608 sinfo.codec_name = stats.codec_name; |
| 2646 sinfo.ext_seqnum = stats.ext_seqnum; | 2609 sinfo.ext_seqnum = stats.ext_seqnum; |
| 2647 sinfo.jitter_ms = stats.jitter_ms; | 2610 sinfo.jitter_ms = stats.jitter_ms; |
| 2648 sinfo.rtt_ms = stats.rtt_ms; | 2611 sinfo.rtt_ms = stats.rtt_ms; |
| 2649 sinfo.audio_level = stats.audio_level; | 2612 sinfo.audio_level = stats.audio_level; |
| 2650 sinfo.aec_quality_min = stats.aec_quality_min; | 2613 sinfo.aec_quality_min = stats.aec_quality_min; |
| 2651 sinfo.echo_delay_median_ms = stats.echo_delay_median_ms; | 2614 sinfo.echo_delay_median_ms = stats.echo_delay_median_ms; |
| 2652 sinfo.echo_delay_std_ms = stats.echo_delay_std_ms; | 2615 sinfo.echo_delay_std_ms = stats.echo_delay_std_ms; |
| 2653 sinfo.echo_return_loss = stats.echo_return_loss; | 2616 sinfo.echo_return_loss = stats.echo_return_loss; |
| 2654 sinfo.echo_return_loss_enhancement = stats.echo_return_loss_enhancement; | 2617 sinfo.echo_return_loss_enhancement = stats.echo_return_loss_enhancement; |
| 2655 sinfo.typing_noise_detected = typing_noise_detected_; | 2618 sinfo.typing_noise_detected = |
| 2656 // TODO(solenberg): Move to AudioSendStream. | 2619 (send_ == SEND_NOTHING ? false : stats.typing_noise_detected); |
| 2657 // sinfo.typing_noise_detected = stats.typing_noise_detected; | |
| 2658 info->senders.push_back(sinfo); | 2620 info->senders.push_back(sinfo); |
| 2659 } | 2621 } |
| 2660 | 2622 |
| 2661 // Get SSRC and stats for each receiver. | 2623 // Get SSRC and stats for each receiver. |
| 2662 RTC_DCHECK(info->receivers.size() == 0); | 2624 RTC_DCHECK(info->receivers.size() == 0); |
| 2663 for (const auto& stream : receive_streams_) { | 2625 for (const auto& stream : receive_streams_) { |
| 2664 webrtc::AudioReceiveStream::Stats stats = stream.second->GetStats(); | 2626 webrtc::AudioReceiveStream::Stats stats = stream.second->GetStats(); |
| 2665 VoiceReceiverInfo rinfo; | 2627 VoiceReceiverInfo rinfo; |
| 2666 rinfo.add_ssrc(stats.remote_ssrc); | 2628 rinfo.add_ssrc(stats.remote_ssrc); |
| 2667 rinfo.bytes_rcvd = stats.bytes_rcvd; | 2629 rinfo.bytes_rcvd = stats.bytes_rcvd; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2687 rinfo.decoding_plc = stats.decoding_plc; | 2649 rinfo.decoding_plc = stats.decoding_plc; |
| 2688 rinfo.decoding_cng = stats.decoding_cng; | 2650 rinfo.decoding_cng = stats.decoding_cng; |
| 2689 rinfo.decoding_plc_cng = stats.decoding_plc_cng; | 2651 rinfo.decoding_plc_cng = stats.decoding_plc_cng; |
| 2690 rinfo.capture_start_ntp_time_ms = stats.capture_start_ntp_time_ms; | 2652 rinfo.capture_start_ntp_time_ms = stats.capture_start_ntp_time_ms; |
| 2691 info->receivers.push_back(rinfo); | 2653 info->receivers.push_back(rinfo); |
| 2692 } | 2654 } |
| 2693 | 2655 |
| 2694 return true; | 2656 return true; |
| 2695 } | 2657 } |
| 2696 | 2658 |
| 2697 void WebRtcVoiceMediaChannel::OnError(int error) { | |
| 2698 if (send_ == SEND_NOTHING) { | |
| 2699 return; | |
| 2700 } | |
| 2701 if (error == VE_TYPING_NOISE_WARNING) { | |
| 2702 typing_noise_detected_ = true; | |
| 2703 } else if (error == VE_TYPING_NOISE_OFF_WARNING) { | |
| 2704 typing_noise_detected_ = false; | |
| 2705 } | |
| 2706 } | |
| 2707 | |
| 2708 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { | 2659 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { |
| 2709 unsigned int ulevel = 0; | 2660 unsigned int ulevel = 0; |
| 2710 int ret = engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); | 2661 int ret = engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); |
| 2711 return (ret == 0) ? static_cast<int>(ulevel) : -1; | 2662 return (ret == 0) ? static_cast<int>(ulevel) : -1; |
| 2712 } | 2663 } |
| 2713 | 2664 |
| 2714 int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32_t ssrc) const { | 2665 int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32_t ssrc) const { |
| 2715 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2666 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 2716 const auto it = receive_channels_.find(ssrc); | 2667 const auto it = receive_channels_.find(ssrc); |
| 2717 if (it != receive_channels_.end()) { | 2668 if (it != receive_channels_.end()) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2780 LOG_RTCERR1(StartPlayout, channel); | 2731 LOG_RTCERR1(StartPlayout, channel); |
| 2781 return false; | 2732 return false; |
| 2782 } | 2733 } |
| 2783 } else { | 2734 } else { |
| 2784 LOG(LS_INFO) << "Stopping playout for channel #" << channel; | 2735 LOG(LS_INFO) << "Stopping playout for channel #" << channel; |
| 2785 engine()->voe()->base()->StopPlayout(channel); | 2736 engine()->voe()->base()->StopPlayout(channel); |
| 2786 } | 2737 } |
| 2787 return true; | 2738 return true; |
| 2788 } | 2739 } |
| 2789 | 2740 |
| 2790 // Convert VoiceEngine error code into VoiceMediaChannel::Error enum. | |
| 2791 VoiceMediaChannel::Error | |
| 2792 WebRtcVoiceMediaChannel::WebRtcErrorToChannelError(int err_code) { | |
| 2793 switch (err_code) { | |
| 2794 case 0: | |
| 2795 return ERROR_NONE; | |
| 2796 case VE_CANNOT_START_RECORDING: | |
| 2797 case VE_MIC_VOL_ERROR: | |
| 2798 case VE_GET_MIC_VOL_ERROR: | |
| 2799 case VE_CANNOT_ACCESS_MIC_VOL: | |
| 2800 return ERROR_REC_DEVICE_OPEN_FAILED; | |
| 2801 case VE_SATURATION_WARNING: | |
| 2802 return ERROR_REC_DEVICE_SATURATION; | |
| 2803 case VE_REC_DEVICE_REMOVED: | |
| 2804 return ERROR_REC_DEVICE_REMOVED; | |
| 2805 case VE_RUNTIME_REC_WARNING: | |
| 2806 case VE_RUNTIME_REC_ERROR: | |
| 2807 return ERROR_REC_RUNTIME_ERROR; | |
| 2808 case VE_CANNOT_START_PLAYOUT: | |
| 2809 case VE_SPEAKER_VOL_ERROR: | |
| 2810 case VE_GET_SPEAKER_VOL_ERROR: | |
| 2811 case VE_CANNOT_ACCESS_SPEAKER_VOL: | |
| 2812 return ERROR_PLAY_DEVICE_OPEN_FAILED; | |
| 2813 case VE_RUNTIME_PLAY_WARNING: | |
| 2814 case VE_RUNTIME_PLAY_ERROR: | |
| 2815 return ERROR_PLAY_RUNTIME_ERROR; | |
| 2816 case VE_TYPING_NOISE_WARNING: | |
| 2817 return ERROR_REC_TYPING_NOISE_DETECTED; | |
| 2818 default: | |
| 2819 return VoiceMediaChannel::ERROR_OTHER; | |
| 2820 } | |
| 2821 } | |
| 2822 | |
| 2823 bool WebRtcVoiceMediaChannel::SetHeaderExtension(ExtensionSetterFunction setter, | 2741 bool WebRtcVoiceMediaChannel::SetHeaderExtension(ExtensionSetterFunction setter, |
| 2824 int channel_id, const RtpHeaderExtension* extension) { | 2742 int channel_id, const RtpHeaderExtension* extension) { |
| 2825 bool enable = false; | 2743 bool enable = false; |
| 2826 int id = 0; | 2744 int id = 0; |
| 2827 std::string uri; | 2745 std::string uri; |
| 2828 if (extension) { | 2746 if (extension) { |
| 2829 enable = true; | 2747 enable = true; |
| 2830 id = extension->id; | 2748 id = extension->id; |
| 2831 uri = extension->uri; | 2749 uri = extension->uri; |
| 2832 } | 2750 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2893 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | 2811 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); |
| 2894 return false; | 2812 return false; |
| 2895 } | 2813 } |
| 2896 } | 2814 } |
| 2897 return true; | 2815 return true; |
| 2898 } | 2816 } |
| 2899 | 2817 |
| 2900 } // namespace cricket | 2818 } // namespace cricket |
| 2901 | 2819 |
| 2902 #endif // HAVE_WEBRTC_VOICE | 2820 #endif // HAVE_WEBRTC_VOICE |
| OLD | NEW |