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 22 matching lines...) Expand all Loading... |
33 #include "webrtc/media/base/mediaconstants.h" | 33 #include "webrtc/media/base/mediaconstants.h" |
34 #include "webrtc/media/base/streamparams.h" | 34 #include "webrtc/media/base/streamparams.h" |
35 #include "webrtc/media/engine/apm_helpers.h" | 35 #include "webrtc/media/engine/apm_helpers.h" |
36 #include "webrtc/media/engine/payload_type_mapper.h" | 36 #include "webrtc/media/engine/payload_type_mapper.h" |
37 #include "webrtc/media/engine/webrtcmediaengine.h" | 37 #include "webrtc/media/engine/webrtcmediaengine.h" |
38 #include "webrtc/media/engine/webrtcvoe.h" | 38 #include "webrtc/media/engine/webrtcvoe.h" |
39 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" | 39 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" |
40 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" | 40 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" |
41 #include "webrtc/modules/audio_processing/include/audio_processing.h" | 41 #include "webrtc/modules/audio_processing/include/audio_processing.h" |
42 #include "webrtc/system_wrappers/include/field_trial.h" | 42 #include "webrtc/system_wrappers/include/field_trial.h" |
| 43 #include "webrtc/system_wrappers/include/metrics.h" |
43 #include "webrtc/system_wrappers/include/trace.h" | 44 #include "webrtc/system_wrappers/include/trace.h" |
44 #include "webrtc/voice_engine/transmit_mixer.h" | 45 #include "webrtc/voice_engine/transmit_mixer.h" |
45 | 46 |
46 namespace cricket { | 47 namespace cricket { |
47 namespace { | 48 namespace { |
48 | 49 |
| 50 constexpr size_t kMaxUnsignaledRecvStreams = 50; |
| 51 |
49 const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo | | 52 const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo | |
50 webrtc::kTraceWarning | webrtc::kTraceError | | 53 webrtc::kTraceWarning | webrtc::kTraceError | |
51 webrtc::kTraceCritical; | 54 webrtc::kTraceCritical; |
52 const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo | | 55 const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo | |
53 webrtc::kTraceInfo; | 56 webrtc::kTraceInfo; |
54 | 57 |
55 // On Windows Vista and newer, Microsoft introduced the concept of "Default | 58 // On Windows Vista and newer, Microsoft introduced the concept of "Default |
56 // Communications Device". This means that there are two types of default | 59 // Communications Device". This means that there are two types of default |
57 // devices (old Wave Audio style default and Default Communications Device). | 60 // devices (old Wave Audio style default and Default Communications Device). |
58 // | 61 // |
(...skipping 2171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2230 if (!ValidateStreamParams(sp)) { | 2233 if (!ValidateStreamParams(sp)) { |
2231 return false; | 2234 return false; |
2232 } | 2235 } |
2233 | 2236 |
2234 const uint32_t ssrc = sp.first_ssrc(); | 2237 const uint32_t ssrc = sp.first_ssrc(); |
2235 if (ssrc == 0) { | 2238 if (ssrc == 0) { |
2236 LOG(LS_WARNING) << "AddRecvStream with ssrc==0 is not supported."; | 2239 LOG(LS_WARNING) << "AddRecvStream with ssrc==0 is not supported."; |
2237 return false; | 2240 return false; |
2238 } | 2241 } |
2239 | 2242 |
2240 // If the default receive stream was created with this ssrc, we unmark it as | 2243 // If this stream was previously received unsignaled, we promote it, possibly |
2241 // being the default stream, and possibly recreate the AudioReceiveStream, if | 2244 // recreating the AudioReceiveStream, if sync_label has changed. |
2242 // sync_label has changed. | 2245 if (MaybeDeregisterUnsignaledRecvStream(ssrc)) { |
2243 if (IsDefaultRecvStream(ssrc)) { | |
2244 recv_streams_[ssrc]->MaybeRecreateAudioReceiveStream(sp.sync_label); | 2246 recv_streams_[ssrc]->MaybeRecreateAudioReceiveStream(sp.sync_label); |
2245 default_recv_ssrc_ = -1; | |
2246 return true; | 2247 return true; |
2247 } | 2248 } |
2248 | 2249 |
2249 if (GetReceiveChannelId(ssrc) != -1) { | 2250 if (GetReceiveChannelId(ssrc) != -1) { |
2250 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; | 2251 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; |
2251 return false; | 2252 return false; |
2252 } | 2253 } |
2253 | 2254 |
2254 // Create a new channel for receiving audio data. | 2255 // Create a new channel for receiving audio data. |
2255 const int channel = CreateVoEChannel(); | 2256 const int channel = CreateVoEChannel(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2299 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2300 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2300 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; | 2301 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; |
2301 | 2302 |
2302 const auto it = recv_streams_.find(ssrc); | 2303 const auto it = recv_streams_.find(ssrc); |
2303 if (it == recv_streams_.end()) { | 2304 if (it == recv_streams_.end()) { |
2304 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc | 2305 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc |
2305 << " which doesn't exist."; | 2306 << " which doesn't exist."; |
2306 return false; | 2307 return false; |
2307 } | 2308 } |
2308 | 2309 |
2309 // Deregister default channel, if that's the one being destroyed. | 2310 MaybeDeregisterUnsignaledRecvStream(ssrc); |
2310 if (IsDefaultRecvStream(ssrc)) { | |
2311 default_recv_ssrc_ = -1; | |
2312 } | |
2313 | 2311 |
2314 const int channel = it->second->channel(); | 2312 const int channel = it->second->channel(); |
2315 | 2313 |
2316 // Clean up and delete the receive stream+channel. | 2314 // Clean up and delete the receive stream+channel. |
2317 LOG(LS_INFO) << "Removing audio receive stream " << ssrc | 2315 LOG(LS_INFO) << "Removing audio receive stream " << ssrc |
2318 << " with VoiceEngine channel #" << channel << "."; | 2316 << " with VoiceEngine channel #" << channel << "."; |
2319 it->second->SetRawAudioSink(nullptr); | 2317 it->second->SetRawAudioSink(nullptr); |
2320 delete it->second; | 2318 delete it->second; |
2321 recv_streams_.erase(it); | 2319 recv_streams_.erase(it); |
2322 return DeleteVoEChannel(channel); | 2320 return DeleteVoEChannel(channel); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2362 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2360 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2363 int highest = 0; | 2361 int highest = 0; |
2364 for (const auto& ch : recv_streams_) { | 2362 for (const auto& ch : recv_streams_) { |
2365 highest = std::max(GetOutputLevel(ch.second->channel()), highest); | 2363 highest = std::max(GetOutputLevel(ch.second->channel()), highest); |
2366 } | 2364 } |
2367 return highest; | 2365 return highest; |
2368 } | 2366 } |
2369 | 2367 |
2370 bool WebRtcVoiceMediaChannel::SetOutputVolume(uint32_t ssrc, double volume) { | 2368 bool WebRtcVoiceMediaChannel::SetOutputVolume(uint32_t ssrc, double volume) { |
2371 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2369 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 2370 std::vector<uint32_t> ssrcs(1, ssrc); |
2372 if (ssrc == 0) { | 2371 if (ssrc == 0) { |
2373 default_recv_volume_ = volume; | 2372 default_recv_volume_ = volume; |
2374 if (default_recv_ssrc_ == -1) { | 2373 ssrcs = unsignaled_recv_ssrcs_; |
2375 return true; | 2374 } |
| 2375 for (uint32_t ssrc : ssrcs) { |
| 2376 const auto it = recv_streams_.find(ssrc); |
| 2377 if (it == recv_streams_.end()) { |
| 2378 LOG(LS_WARNING) << "SetOutputVolume: no recv stream " << ssrc; |
| 2379 return false; |
2376 } | 2380 } |
2377 ssrc = static_cast<uint32_t>(default_recv_ssrc_); | 2381 it->second->SetOutputVolume(volume); |
| 2382 LOG(LS_INFO) << "SetOutputVolume() to " << volume |
| 2383 << " for recv stream with ssrc " << ssrc; |
2378 } | 2384 } |
2379 const auto it = recv_streams_.find(ssrc); | |
2380 if (it == recv_streams_.end()) { | |
2381 LOG(LS_WARNING) << "SetOutputVolume: no recv stream" << ssrc; | |
2382 return false; | |
2383 } | |
2384 it->second->SetOutputVolume(volume); | |
2385 LOG(LS_INFO) << "SetOutputVolume() to " << volume | |
2386 << " for recv stream with ssrc " << ssrc; | |
2387 return true; | 2385 return true; |
2388 } | 2386 } |
2389 | 2387 |
2390 bool WebRtcVoiceMediaChannel::CanInsertDtmf() { | 2388 bool WebRtcVoiceMediaChannel::CanInsertDtmf() { |
2391 return dtmf_payload_type_ ? true : false; | 2389 return dtmf_payload_type_ ? true : false; |
2392 } | 2390 } |
2393 | 2391 |
2394 bool WebRtcVoiceMediaChannel::InsertDtmf(uint32_t ssrc, int event, | 2392 bool WebRtcVoiceMediaChannel::InsertDtmf(uint32_t ssrc, int event, |
2395 int duration) { | 2393 int duration) { |
2396 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2394 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
(...skipping 30 matching lines...) Expand all Loading... |
2427 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, | 2425 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, |
2428 packet_time.not_before); | 2426 packet_time.not_before); |
2429 webrtc::PacketReceiver::DeliveryStatus delivery_result = | 2427 webrtc::PacketReceiver::DeliveryStatus delivery_result = |
2430 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, | 2428 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, |
2431 packet->cdata(), packet->size(), | 2429 packet->cdata(), packet->size(), |
2432 webrtc_packet_time); | 2430 webrtc_packet_time); |
2433 if (delivery_result != webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC) { | 2431 if (delivery_result != webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC) { |
2434 return; | 2432 return; |
2435 } | 2433 } |
2436 | 2434 |
2437 // Create a default receive stream for this unsignalled and previously not | 2435 // Create an unsignaled receive stream for this previously not received ssrc. |
2438 // received ssrc. If there already is a default receive stream, delete it. | 2436 // If there already is N unsignaled receive streams, delete the oldest. |
2439 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5208 | 2437 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5208 |
2440 uint32_t ssrc = 0; | 2438 uint32_t ssrc = 0; |
2441 if (!GetRtpSsrc(packet->cdata(), packet->size(), &ssrc)) { | 2439 if (!GetRtpSsrc(packet->cdata(), packet->size(), &ssrc)) { |
2442 return; | 2440 return; |
2443 } | 2441 } |
| 2442 RTC_DCHECK(std::find(unsignaled_recv_ssrcs_.begin(), |
| 2443 unsignaled_recv_ssrcs_.end(), ssrc) == unsignaled_recv_ssrcs_.end()); |
2444 | 2444 |
| 2445 // Add new stream. |
2445 StreamParams sp; | 2446 StreamParams sp; |
2446 sp.ssrcs.push_back(ssrc); | 2447 sp.ssrcs.push_back(ssrc); |
2447 LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; | 2448 LOG(LS_INFO) << "Creating unsignaled receive stream for SSRC=" << ssrc; |
2448 if (!AddRecvStream(sp)) { | 2449 if (!AddRecvStream(sp)) { |
2449 LOG(LS_WARNING) << "Could not create default receive stream."; | 2450 LOG(LS_WARNING) << "Could not create unsignaled receive stream."; |
2450 return; | 2451 return; |
2451 } | 2452 } |
2452 if (default_recv_ssrc_ != -1) { | 2453 unsignaled_recv_ssrcs_.push_back(ssrc); |
2453 LOG(LS_INFO) << "Removing default receive stream with ssrc " | 2454 RTC_HISTOGRAM_COUNTS_LINEAR( |
2454 << default_recv_ssrc_; | 2455 "WebRTC.Audio.NumOfUnsignaledStreams", unsignaled_recv_ssrcs_.size(), 1, |
2455 RTC_DCHECK_NE(ssrc, default_recv_ssrc_); | 2456 100, 101); |
2456 RemoveRecvStream(default_recv_ssrc_); | 2457 |
| 2458 // Remove oldest unsignaled stream, if we have too many. |
| 2459 if (unsignaled_recv_ssrcs_.size() > kMaxUnsignaledRecvStreams) { |
| 2460 uint32_t remove_ssrc = unsignaled_recv_ssrcs_.front(); |
| 2461 LOG(LS_INFO) << "Removing unsignaled receive stream with SSRC=" |
| 2462 << remove_ssrc; |
| 2463 RemoveRecvStream(remove_ssrc); |
2457 } | 2464 } |
2458 default_recv_ssrc_ = ssrc; | 2465 RTC_DCHECK_GE(kMaxUnsignaledRecvStreams, unsignaled_recv_ssrcs_.size()); |
2459 | 2466 |
2460 SetOutputVolume(default_recv_ssrc_, default_recv_volume_); | 2467 SetOutputVolume(ssrc, default_recv_volume_); |
| 2468 |
| 2469 // The default sink can only be attached to one stream at a time, so we hook |
| 2470 // it up to the *latest* unsignaled stream we've seen, in order to support the |
| 2471 // case where the SSRC of one unsignaled stream changes. |
2461 if (default_sink_) { | 2472 if (default_sink_) { |
| 2473 for (uint32_t drop_ssrc : unsignaled_recv_ssrcs_) { |
| 2474 auto it = recv_streams_.find(drop_ssrc); |
| 2475 it->second->SetRawAudioSink(nullptr); |
| 2476 } |
2462 std::unique_ptr<webrtc::AudioSinkInterface> proxy_sink( | 2477 std::unique_ptr<webrtc::AudioSinkInterface> proxy_sink( |
2463 new ProxySink(default_sink_.get())); | 2478 new ProxySink(default_sink_.get())); |
2464 SetRawAudioSink(default_recv_ssrc_, std::move(proxy_sink)); | 2479 SetRawAudioSink(ssrc, std::move(proxy_sink)); |
2465 } | 2480 } |
| 2481 |
2466 delivery_result = call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, | 2482 delivery_result = call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, |
2467 packet->cdata(), | 2483 packet->cdata(), |
2468 packet->size(), | 2484 packet->size(), |
2469 webrtc_packet_time); | 2485 webrtc_packet_time); |
2470 RTC_DCHECK_NE(webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC, delivery_result); | 2486 RTC_DCHECK_NE(webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC, delivery_result); |
2471 } | 2487 } |
2472 | 2488 |
2473 void WebRtcVoiceMediaChannel::OnRtcpReceived( | 2489 void WebRtcVoiceMediaChannel::OnRtcpReceived( |
2474 rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { | 2490 rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { |
2475 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2491 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2620 return true; | 2636 return true; |
2621 } | 2637 } |
2622 | 2638 |
2623 void WebRtcVoiceMediaChannel::SetRawAudioSink( | 2639 void WebRtcVoiceMediaChannel::SetRawAudioSink( |
2624 uint32_t ssrc, | 2640 uint32_t ssrc, |
2625 std::unique_ptr<webrtc::AudioSinkInterface> sink) { | 2641 std::unique_ptr<webrtc::AudioSinkInterface> sink) { |
2626 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2642 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2627 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::SetRawAudioSink: ssrc:" << ssrc | 2643 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::SetRawAudioSink: ssrc:" << ssrc |
2628 << " " << (sink ? "(ptr)" : "NULL"); | 2644 << " " << (sink ? "(ptr)" : "NULL"); |
2629 if (ssrc == 0) { | 2645 if (ssrc == 0) { |
2630 if (default_recv_ssrc_ != -1) { | 2646 if (!unsignaled_recv_ssrcs_.empty()) { |
2631 std::unique_ptr<webrtc::AudioSinkInterface> proxy_sink( | 2647 std::unique_ptr<webrtc::AudioSinkInterface> proxy_sink( |
2632 sink ? new ProxySink(sink.get()) : nullptr); | 2648 sink ? new ProxySink(sink.get()) : nullptr); |
2633 SetRawAudioSink(default_recv_ssrc_, std::move(proxy_sink)); | 2649 SetRawAudioSink(unsignaled_recv_ssrcs_.back(), std::move(proxy_sink)); |
2634 } | 2650 } |
2635 default_sink_ = std::move(sink); | 2651 default_sink_ = std::move(sink); |
2636 return; | 2652 return; |
2637 } | 2653 } |
2638 const auto it = recv_streams_.find(ssrc); | 2654 const auto it = recv_streams_.find(ssrc); |
2639 if (it == recv_streams_.end()) { | 2655 if (it == recv_streams_.end()) { |
2640 LOG(LS_WARNING) << "SetRawAudioSink: no recv stream" << ssrc; | 2656 LOG(LS_WARNING) << "SetRawAudioSink: no recv stream " << ssrc; |
2641 return; | 2657 return; |
2642 } | 2658 } |
2643 it->second->SetRawAudioSink(std::move(sink)); | 2659 it->second->SetRawAudioSink(std::move(sink)); |
2644 } | 2660 } |
2645 | 2661 |
2646 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { | 2662 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { |
2647 unsigned int ulevel = 0; | 2663 unsigned int ulevel = 0; |
2648 int ret = engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); | 2664 int ret = engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); |
2649 return (ret == 0) ? static_cast<int>(ulevel) : -1; | 2665 return (ret == 0) ? static_cast<int>(ulevel) : -1; |
2650 } | 2666 } |
2651 | 2667 |
2652 int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32_t ssrc) const { | 2668 int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32_t ssrc) const { |
2653 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2669 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2654 const auto it = recv_streams_.find(ssrc); | 2670 const auto it = recv_streams_.find(ssrc); |
2655 if (it != recv_streams_.end()) { | 2671 if (it != recv_streams_.end()) { |
2656 return it->second->channel(); | 2672 return it->second->channel(); |
2657 } | 2673 } |
2658 return -1; | 2674 return -1; |
2659 } | 2675 } |
2660 | 2676 |
2661 int WebRtcVoiceMediaChannel::GetSendChannelId(uint32_t ssrc) const { | 2677 int WebRtcVoiceMediaChannel::GetSendChannelId(uint32_t ssrc) const { |
2662 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2678 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2663 const auto it = send_streams_.find(ssrc); | 2679 const auto it = send_streams_.find(ssrc); |
2664 if (it != send_streams_.end()) { | 2680 if (it != send_streams_.end()) { |
2665 return it->second->channel(); | 2681 return it->second->channel(); |
2666 } | 2682 } |
2667 return -1; | 2683 return -1; |
2668 } | 2684 } |
| 2685 |
| 2686 bool WebRtcVoiceMediaChannel:: |
| 2687 MaybeDeregisterUnsignaledRecvStream(uint32_t ssrc) { |
| 2688 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 2689 auto it = std::find(unsignaled_recv_ssrcs_.begin(), |
| 2690 unsignaled_recv_ssrcs_.end(), |
| 2691 ssrc); |
| 2692 if (it != unsignaled_recv_ssrcs_.end()) { |
| 2693 unsignaled_recv_ssrcs_.erase(it); |
| 2694 return true; |
| 2695 } |
| 2696 return false; |
| 2697 } |
2669 } // namespace cricket | 2698 } // namespace cricket |
2670 | 2699 |
2671 #endif // HAVE_WEBRTC_VOICE | 2700 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |