OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 26 matching lines...) Expand all Loading... |
37 #include "webrtc/media/engine/webrtcvoe.h" | 37 #include "webrtc/media/engine/webrtcvoe.h" |
38 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" | 38 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" |
39 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" | 39 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" |
40 #include "webrtc/modules/audio_processing/include/audio_processing.h" | 40 #include "webrtc/modules/audio_processing/include/audio_processing.h" |
41 #include "webrtc/system_wrappers/include/field_trial.h" | 41 #include "webrtc/system_wrappers/include/field_trial.h" |
42 #include "webrtc/system_wrappers/include/trace.h" | 42 #include "webrtc/system_wrappers/include/trace.h" |
43 | 43 |
44 namespace cricket { | 44 namespace cricket { |
45 namespace { | 45 namespace { |
46 | 46 |
| 47 constexpr size_t kMaxUnsignaledRecvStreams = 50; |
| 48 |
47 const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo | | 49 const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo | |
48 webrtc::kTraceWarning | webrtc::kTraceError | | 50 webrtc::kTraceWarning | webrtc::kTraceError | |
49 webrtc::kTraceCritical; | 51 webrtc::kTraceCritical; |
50 const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo | | 52 const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo | |
51 webrtc::kTraceInfo; | 53 webrtc::kTraceInfo; |
52 | 54 |
53 // On Windows Vista and newer, Microsoft introduced the concept of "Default | 55 // On Windows Vista and newer, Microsoft introduced the concept of "Default |
54 // Communications Device". This means that there are two types of default | 56 // Communications Device". This means that there are two types of default |
55 // devices (old Wave Audio style default and Default Communications Device). | 57 // devices (old Wave Audio style default and Default Communications Device). |
56 // | 58 // |
(...skipping 2212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2269 if (!ValidateStreamParams(sp)) { | 2271 if (!ValidateStreamParams(sp)) { |
2270 return false; | 2272 return false; |
2271 } | 2273 } |
2272 | 2274 |
2273 const uint32_t ssrc = sp.first_ssrc(); | 2275 const uint32_t ssrc = sp.first_ssrc(); |
2274 if (ssrc == 0) { | 2276 if (ssrc == 0) { |
2275 LOG(LS_WARNING) << "AddRecvStream with ssrc==0 is not supported."; | 2277 LOG(LS_WARNING) << "AddRecvStream with ssrc==0 is not supported."; |
2276 return false; | 2278 return false; |
2277 } | 2279 } |
2278 | 2280 |
2279 // Remove the default receive stream if one had been created with this ssrc; | 2281 // If this stream was previously received unsignaled, remove it first. |
2280 // we'll recreate it then. | 2282 if (MaybeDeregisterUnsignaledRecvStream(ssrc)) { |
2281 if (IsDefaultRecvStream(ssrc)) { | |
2282 RemoveRecvStream(ssrc); | 2283 RemoveRecvStream(ssrc); |
2283 } | 2284 } |
2284 | 2285 |
2285 if (GetReceiveChannelId(ssrc) != -1) { | 2286 if (GetReceiveChannelId(ssrc) != -1) { |
2286 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; | 2287 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; |
2287 return false; | 2288 return false; |
2288 } | 2289 } |
2289 | 2290 |
2290 // Create a new channel for receiving audio data. | 2291 // Create a new channel for receiving audio data. |
2291 const int channel = CreateVoEChannel(); | 2292 const int channel = CreateVoEChannel(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2335 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2336 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2336 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; | 2337 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; |
2337 | 2338 |
2338 const auto it = recv_streams_.find(ssrc); | 2339 const auto it = recv_streams_.find(ssrc); |
2339 if (it == recv_streams_.end()) { | 2340 if (it == recv_streams_.end()) { |
2340 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc | 2341 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc |
2341 << " which doesn't exist."; | 2342 << " which doesn't exist."; |
2342 return false; | 2343 return false; |
2343 } | 2344 } |
2344 | 2345 |
2345 // Deregister default channel, if that's the one being destroyed. | 2346 MaybeDeregisterUnsignaledRecvStream(ssrc); |
2346 if (IsDefaultRecvStream(ssrc)) { | |
2347 default_recv_ssrc_ = -1; | |
2348 } | |
2349 | 2347 |
2350 const int channel = it->second->channel(); | 2348 const int channel = it->second->channel(); |
2351 | 2349 |
2352 // Clean up and delete the receive stream+channel. | 2350 // Clean up and delete the receive stream+channel. |
2353 LOG(LS_INFO) << "Removing audio receive stream " << ssrc | 2351 LOG(LS_INFO) << "Removing audio receive stream " << ssrc |
2354 << " with VoiceEngine channel #" << channel << "."; | 2352 << " with VoiceEngine channel #" << channel << "."; |
2355 it->second->SetRawAudioSink(nullptr); | 2353 it->second->SetRawAudioSink(nullptr); |
2356 delete it->second; | 2354 delete it->second; |
2357 recv_streams_.erase(it); | 2355 recv_streams_.erase(it); |
2358 return DeleteVoEChannel(channel); | 2356 return DeleteVoEChannel(channel); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2398 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2396 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2399 int highest = 0; | 2397 int highest = 0; |
2400 for (const auto& ch : recv_streams_) { | 2398 for (const auto& ch : recv_streams_) { |
2401 highest = std::max(GetOutputLevel(ch.second->channel()), highest); | 2399 highest = std::max(GetOutputLevel(ch.second->channel()), highest); |
2402 } | 2400 } |
2403 return highest; | 2401 return highest; |
2404 } | 2402 } |
2405 | 2403 |
2406 bool WebRtcVoiceMediaChannel::SetOutputVolume(uint32_t ssrc, double volume) { | 2404 bool WebRtcVoiceMediaChannel::SetOutputVolume(uint32_t ssrc, double volume) { |
2407 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2405 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 2406 std::vector<uint32_t> ssrcs(1, ssrc); |
2408 if (ssrc == 0) { | 2407 if (ssrc == 0) { |
2409 default_recv_volume_ = volume; | 2408 default_recv_volume_ = volume; |
2410 if (default_recv_ssrc_ == -1) { | 2409 ssrcs = unsignaled_recv_ssrcs_; |
2411 return true; | 2410 } |
| 2411 for (uint32_t ssrc : ssrcs) { |
| 2412 const auto it = recv_streams_.find(ssrc); |
| 2413 if (it == recv_streams_.end()) { |
| 2414 LOG(LS_WARNING) << "SetOutputVolume: no recv stream " << ssrc; |
| 2415 return false; |
2412 } | 2416 } |
2413 ssrc = static_cast<uint32_t>(default_recv_ssrc_); | 2417 it->second->SetOutputVolume(volume); |
| 2418 LOG(LS_INFO) << "SetOutputVolume() to " << volume |
| 2419 << " for recv stream with ssrc " << ssrc; |
2414 } | 2420 } |
2415 const auto it = recv_streams_.find(ssrc); | |
2416 if (it == recv_streams_.end()) { | |
2417 LOG(LS_WARNING) << "SetOutputVolume: no recv stream" << ssrc; | |
2418 return false; | |
2419 } | |
2420 it->second->SetOutputVolume(volume); | |
2421 LOG(LS_INFO) << "SetOutputVolume() to " << volume | |
2422 << " for recv stream with ssrc " << ssrc; | |
2423 return true; | 2421 return true; |
2424 } | 2422 } |
2425 | 2423 |
2426 bool WebRtcVoiceMediaChannel::CanInsertDtmf() { | 2424 bool WebRtcVoiceMediaChannel::CanInsertDtmf() { |
2427 return dtmf_payload_type_ ? true : false; | 2425 return dtmf_payload_type_ ? true : false; |
2428 } | 2426 } |
2429 | 2427 |
2430 bool WebRtcVoiceMediaChannel::InsertDtmf(uint32_t ssrc, int event, | 2428 bool WebRtcVoiceMediaChannel::InsertDtmf(uint32_t ssrc, int event, |
2431 int duration) { | 2429 int duration) { |
2432 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2430 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
(...skipping 30 matching lines...) Expand all Loading... |
2463 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, | 2461 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, |
2464 packet_time.not_before); | 2462 packet_time.not_before); |
2465 webrtc::PacketReceiver::DeliveryStatus delivery_result = | 2463 webrtc::PacketReceiver::DeliveryStatus delivery_result = |
2466 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, | 2464 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, |
2467 packet->cdata(), packet->size(), | 2465 packet->cdata(), packet->size(), |
2468 webrtc_packet_time); | 2466 webrtc_packet_time); |
2469 if (delivery_result != webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC) { | 2467 if (delivery_result != webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC) { |
2470 return; | 2468 return; |
2471 } | 2469 } |
2472 | 2470 |
2473 // Create a default receive stream for this unsignalled and previously not | 2471 // Create an unsignaled receive stream for this previously not received ssrc. |
2474 // received ssrc. If there already is a default receive stream, delete it. | 2472 // If there already is N unsignaled receive streams, delete the oldest. |
2475 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5208 | 2473 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5208 |
2476 uint32_t ssrc = 0; | 2474 uint32_t ssrc = 0; |
2477 if (!GetRtpSsrc(packet->cdata(), packet->size(), &ssrc)) { | 2475 if (!GetRtpSsrc(packet->cdata(), packet->size(), &ssrc)) { |
2478 return; | 2476 return; |
2479 } | 2477 } |
| 2478 RTC_DCHECK(std::find(unsignaled_recv_ssrcs_.begin(), |
| 2479 unsignaled_recv_ssrcs_.end(), ssrc) == unsignaled_recv_ssrcs_.end()); |
2480 | 2480 |
| 2481 // Add new stream. |
2481 StreamParams sp; | 2482 StreamParams sp; |
2482 sp.ssrcs.push_back(ssrc); | 2483 sp.ssrcs.push_back(ssrc); |
2483 LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; | 2484 LOG(LS_INFO) << "Creating unsignaled receive stream for SSRC=" << ssrc; |
2484 if (!AddRecvStream(sp)) { | 2485 if (!AddRecvStream(sp)) { |
2485 LOG(LS_WARNING) << "Could not create default receive stream."; | 2486 LOG(LS_WARNING) << "Could not create unsignaled receive stream."; |
2486 return; | 2487 return; |
2487 } | 2488 } |
2488 if (default_recv_ssrc_ != -1) { | 2489 unsignaled_recv_ssrcs_.push_back(ssrc); |
2489 LOG(LS_INFO) << "Removing default receive stream with ssrc " | 2490 |
2490 << default_recv_ssrc_; | 2491 // Remove oldest unsignaled stream, if we have too many. |
2491 RTC_DCHECK_NE(ssrc, default_recv_ssrc_); | 2492 if (unsignaled_recv_ssrcs_.size() > kMaxUnsignaledRecvStreams) { |
2492 RemoveRecvStream(default_recv_ssrc_); | 2493 uint32_t remove_ssrc = unsignaled_recv_ssrcs_.front(); |
| 2494 LOG(LS_INFO) << "Removing unsignaled receive stream with SSRC=" |
| 2495 << remove_ssrc; |
| 2496 RemoveRecvStream(remove_ssrc); |
2493 } | 2497 } |
2494 default_recv_ssrc_ = ssrc; | 2498 RTC_DCHECK_GE(kMaxUnsignaledRecvStreams, unsignaled_recv_ssrcs_.size()); |
2495 | 2499 |
2496 SetOutputVolume(default_recv_ssrc_, default_recv_volume_); | 2500 SetOutputVolume(ssrc, default_recv_volume_); |
| 2501 |
| 2502 // The default sink can only be attached to one stream at a time, so we hook |
| 2503 // it up to the *latest* unsignaled stream we've seen, in order to support the |
| 2504 // case where the SSRC of one unsignaled stream changes. |
2497 if (default_sink_) { | 2505 if (default_sink_) { |
| 2506 for (uint32_t drop_ssrc : unsignaled_recv_ssrcs_) { |
| 2507 auto it = recv_streams_.find(drop_ssrc); |
| 2508 it->second->SetRawAudioSink(nullptr); |
| 2509 } |
2498 std::unique_ptr<webrtc::AudioSinkInterface> proxy_sink( | 2510 std::unique_ptr<webrtc::AudioSinkInterface> proxy_sink( |
2499 new ProxySink(default_sink_.get())); | 2511 new ProxySink(default_sink_.get())); |
2500 SetRawAudioSink(default_recv_ssrc_, std::move(proxy_sink)); | 2512 SetRawAudioSink(ssrc, std::move(proxy_sink)); |
2501 } | 2513 } |
| 2514 |
2502 delivery_result = call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, | 2515 delivery_result = call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, |
2503 packet->cdata(), | 2516 packet->cdata(), |
2504 packet->size(), | 2517 packet->size(), |
2505 webrtc_packet_time); | 2518 webrtc_packet_time); |
2506 RTC_DCHECK_NE(webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC, delivery_result); | 2519 RTC_DCHECK_NE(webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC, delivery_result); |
2507 } | 2520 } |
2508 | 2521 |
2509 void WebRtcVoiceMediaChannel::OnRtcpReceived( | 2522 void WebRtcVoiceMediaChannel::OnRtcpReceived( |
2510 rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { | 2523 rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { |
2511 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2524 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2656 return true; | 2669 return true; |
2657 } | 2670 } |
2658 | 2671 |
2659 void WebRtcVoiceMediaChannel::SetRawAudioSink( | 2672 void WebRtcVoiceMediaChannel::SetRawAudioSink( |
2660 uint32_t ssrc, | 2673 uint32_t ssrc, |
2661 std::unique_ptr<webrtc::AudioSinkInterface> sink) { | 2674 std::unique_ptr<webrtc::AudioSinkInterface> sink) { |
2662 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2675 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2663 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::SetRawAudioSink: ssrc:" << ssrc | 2676 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::SetRawAudioSink: ssrc:" << ssrc |
2664 << " " << (sink ? "(ptr)" : "NULL"); | 2677 << " " << (sink ? "(ptr)" : "NULL"); |
2665 if (ssrc == 0) { | 2678 if (ssrc == 0) { |
2666 if (default_recv_ssrc_ != -1) { | 2679 if (!unsignaled_recv_ssrcs_.empty()) { |
2667 std::unique_ptr<webrtc::AudioSinkInterface> proxy_sink( | 2680 std::unique_ptr<webrtc::AudioSinkInterface> proxy_sink( |
2668 sink ? new ProxySink(sink.get()) : nullptr); | 2681 sink ? new ProxySink(sink.get()) : nullptr); |
2669 SetRawAudioSink(default_recv_ssrc_, std::move(proxy_sink)); | 2682 SetRawAudioSink(unsignaled_recv_ssrcs_.back(), std::move(proxy_sink)); |
2670 } | 2683 } |
2671 default_sink_ = std::move(sink); | 2684 default_sink_ = std::move(sink); |
2672 return; | 2685 return; |
2673 } | 2686 } |
2674 const auto it = recv_streams_.find(ssrc); | 2687 const auto it = recv_streams_.find(ssrc); |
2675 if (it == recv_streams_.end()) { | 2688 if (it == recv_streams_.end()) { |
2676 LOG(LS_WARNING) << "SetRawAudioSink: no recv stream" << ssrc; | 2689 LOG(LS_WARNING) << "SetRawAudioSink: no recv stream " << ssrc; |
2677 return; | 2690 return; |
2678 } | 2691 } |
2679 it->second->SetRawAudioSink(std::move(sink)); | 2692 it->second->SetRawAudioSink(std::move(sink)); |
2680 } | 2693 } |
2681 | 2694 |
2682 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { | 2695 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { |
2683 unsigned int ulevel = 0; | 2696 unsigned int ulevel = 0; |
2684 int ret = engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); | 2697 int ret = engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); |
2685 return (ret == 0) ? static_cast<int>(ulevel) : -1; | 2698 return (ret == 0) ? static_cast<int>(ulevel) : -1; |
2686 } | 2699 } |
2687 | 2700 |
2688 int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32_t ssrc) const { | 2701 int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32_t ssrc) const { |
2689 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2702 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2690 const auto it = recv_streams_.find(ssrc); | 2703 const auto it = recv_streams_.find(ssrc); |
2691 if (it != recv_streams_.end()) { | 2704 if (it != recv_streams_.end()) { |
2692 return it->second->channel(); | 2705 return it->second->channel(); |
2693 } | 2706 } |
2694 return -1; | 2707 return -1; |
2695 } | 2708 } |
2696 | 2709 |
2697 int WebRtcVoiceMediaChannel::GetSendChannelId(uint32_t ssrc) const { | 2710 int WebRtcVoiceMediaChannel::GetSendChannelId(uint32_t ssrc) const { |
2698 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2711 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2699 const auto it = send_streams_.find(ssrc); | 2712 const auto it = send_streams_.find(ssrc); |
2700 if (it != send_streams_.end()) { | 2713 if (it != send_streams_.end()) { |
2701 return it->second->channel(); | 2714 return it->second->channel(); |
2702 } | 2715 } |
2703 return -1; | 2716 return -1; |
2704 } | 2717 } |
| 2718 |
| 2719 bool WebRtcVoiceMediaChannel:: |
| 2720 MaybeDeregisterUnsignaledRecvStream(uint32_t ssrc) { |
| 2721 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 2722 auto it = std::find(unsignaled_recv_ssrcs_.begin(), |
| 2723 unsignaled_recv_ssrcs_.end(), |
| 2724 ssrc); |
| 2725 if (it != unsignaled_recv_ssrcs_.end()) { |
| 2726 unsignaled_recv_ssrcs_.erase(it); |
| 2727 return true; |
| 2728 } |
| 2729 return false; |
| 2730 } |
2705 } // namespace cricket | 2731 } // namespace cricket |
2706 | 2732 |
2707 #endif // HAVE_WEBRTC_VOICE | 2733 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |