Chromium Code Reviews| 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 (TryDeregisterUnsignaledRecvStream(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 TryDeregisterUnsignaledRecvStream(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_); |
| 2497 if (default_sink_) { | 2501 |
| 2502 // Only set audio sink for first unsignaled stream. | |
|
Taylor Brandstetter
2017/02/17 08:36:14
Is this ok? And should there be a test for this?
the sun
2017/02/17 10:10:56
A) No. I changed it to adding the default sink to
| |
| 2503 if (default_sink_ && unsignaled_recv_ssrcs_.size() == 1) { | |
| 2498 std::unique_ptr<webrtc::AudioSinkInterface> proxy_sink( | 2504 std::unique_ptr<webrtc::AudioSinkInterface> proxy_sink( |
| 2499 new ProxySink(default_sink_.get())); | 2505 new ProxySink(default_sink_.get())); |
| 2500 SetRawAudioSink(default_recv_ssrc_, std::move(proxy_sink)); | 2506 SetRawAudioSink(ssrc, std::move(proxy_sink)); |
| 2501 } | 2507 } |
| 2508 | |
| 2502 delivery_result = call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, | 2509 delivery_result = call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, |
| 2503 packet->cdata(), | 2510 packet->cdata(), |
| 2504 packet->size(), | 2511 packet->size(), |
| 2505 webrtc_packet_time); | 2512 webrtc_packet_time); |
| 2506 RTC_DCHECK_NE(webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC, delivery_result); | 2513 RTC_DCHECK_NE(webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC, delivery_result); |
| 2507 } | 2514 } |
| 2508 | 2515 |
| 2509 void WebRtcVoiceMediaChannel::OnRtcpReceived( | 2516 void WebRtcVoiceMediaChannel::OnRtcpReceived( |
| 2510 rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { | 2517 rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { |
| 2511 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2518 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2656 return true; | 2663 return true; |
| 2657 } | 2664 } |
| 2658 | 2665 |
| 2659 void WebRtcVoiceMediaChannel::SetRawAudioSink( | 2666 void WebRtcVoiceMediaChannel::SetRawAudioSink( |
| 2660 uint32_t ssrc, | 2667 uint32_t ssrc, |
| 2661 std::unique_ptr<webrtc::AudioSinkInterface> sink) { | 2668 std::unique_ptr<webrtc::AudioSinkInterface> sink) { |
| 2662 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2669 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 2663 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::SetRawAudioSink: ssrc:" << ssrc | 2670 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::SetRawAudioSink: ssrc:" << ssrc |
| 2664 << " " << (sink ? "(ptr)" : "NULL"); | 2671 << " " << (sink ? "(ptr)" : "NULL"); |
| 2665 if (ssrc == 0) { | 2672 if (ssrc == 0) { |
| 2666 if (default_recv_ssrc_ != -1) { | 2673 if (unsignaled_recv_ssrcs_.size() == 1) { |
| 2667 std::unique_ptr<webrtc::AudioSinkInterface> proxy_sink( | 2674 std::unique_ptr<webrtc::AudioSinkInterface> proxy_sink( |
| 2668 sink ? new ProxySink(sink.get()) : nullptr); | 2675 sink ? new ProxySink(sink.get()) : nullptr); |
| 2669 SetRawAudioSink(default_recv_ssrc_, std::move(proxy_sink)); | 2676 SetRawAudioSink(unsignaled_recv_ssrcs_.front(), std::move(proxy_sink)); |
| 2670 } | 2677 } |
| 2671 default_sink_ = std::move(sink); | 2678 default_sink_ = std::move(sink); |
| 2672 return; | 2679 return; |
| 2673 } | 2680 } |
| 2674 const auto it = recv_streams_.find(ssrc); | 2681 const auto it = recv_streams_.find(ssrc); |
| 2675 if (it == recv_streams_.end()) { | 2682 if (it == recv_streams_.end()) { |
| 2676 LOG(LS_WARNING) << "SetRawAudioSink: no recv stream" << ssrc; | 2683 LOG(LS_WARNING) << "SetRawAudioSink: no recv stream " << ssrc; |
| 2677 return; | 2684 return; |
| 2678 } | 2685 } |
| 2679 it->second->SetRawAudioSink(std::move(sink)); | 2686 it->second->SetRawAudioSink(std::move(sink)); |
| 2680 } | 2687 } |
| 2681 | 2688 |
| 2682 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { | 2689 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { |
| 2683 unsigned int ulevel = 0; | 2690 unsigned int ulevel = 0; |
| 2684 int ret = engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); | 2691 int ret = engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); |
| 2685 return (ret == 0) ? static_cast<int>(ulevel) : -1; | 2692 return (ret == 0) ? static_cast<int>(ulevel) : -1; |
| 2686 } | 2693 } |
| 2687 | 2694 |
| 2688 int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32_t ssrc) const { | 2695 int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32_t ssrc) const { |
| 2689 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2696 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 2690 const auto it = recv_streams_.find(ssrc); | 2697 const auto it = recv_streams_.find(ssrc); |
| 2691 if (it != recv_streams_.end()) { | 2698 if (it != recv_streams_.end()) { |
| 2692 return it->second->channel(); | 2699 return it->second->channel(); |
| 2693 } | 2700 } |
| 2694 return -1; | 2701 return -1; |
| 2695 } | 2702 } |
| 2696 | 2703 |
| 2697 int WebRtcVoiceMediaChannel::GetSendChannelId(uint32_t ssrc) const { | 2704 int WebRtcVoiceMediaChannel::GetSendChannelId(uint32_t ssrc) const { |
| 2698 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2705 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 2699 const auto it = send_streams_.find(ssrc); | 2706 const auto it = send_streams_.find(ssrc); |
| 2700 if (it != send_streams_.end()) { | 2707 if (it != send_streams_.end()) { |
| 2701 return it->second->channel(); | 2708 return it->second->channel(); |
| 2702 } | 2709 } |
| 2703 return -1; | 2710 return -1; |
| 2704 } | 2711 } |
| 2712 | |
| 2713 bool WebRtcVoiceMediaChannel::TryDeregisterUnsignaledRecvStream(uint32_t ssrc) { | |
| 2714 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
| 2715 auto it = std::find(unsignaled_recv_ssrcs_.begin(), | |
| 2716 unsignaled_recv_ssrcs_.end(), | |
| 2717 ssrc); | |
| 2718 if (it != unsignaled_recv_ssrcs_.end()) { | |
| 2719 unsignaled_recv_ssrcs_.erase(it); | |
| 2720 return true; | |
| 2721 } | |
| 2722 return false; | |
| 2723 } | |
| 2705 } // namespace cricket | 2724 } // namespace cricket |
| 2706 | 2725 |
| 2707 #endif // HAVE_WEBRTC_VOICE | 2726 #endif // HAVE_WEBRTC_VOICE |
| OLD | NEW |