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 |