Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(290)

Side by Side Diff: webrtc/media/engine/webrtcvoiceengine.cc

Issue 2685893002: Support N unsignaled audio streams (Closed)
Patch Set: bad comment Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698