Chromium Code Reviews| Index: webrtc/media/engine/webrtcvoiceengine.cc |
| diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc |
| index f96c8e741e04ad94075ad69add97fab351230e01..d3c168e290d24e05e489013c21d84b320398728a 100644 |
| --- a/webrtc/media/engine/webrtcvoiceengine.cc |
| +++ b/webrtc/media/engine/webrtcvoiceengine.cc |
| @@ -44,6 +44,8 @@ |
| namespace cricket { |
| namespace { |
| +constexpr size_t kMaxUnsignaledRecvStreams = 50; |
| + |
| const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo | |
| webrtc::kTraceWarning | webrtc::kTraceError | |
| webrtc::kTraceCritical; |
| @@ -2276,9 +2278,8 @@ bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { |
| return false; |
| } |
| - // Remove the default receive stream if one had been created with this ssrc; |
| - // we'll recreate it then. |
| - if (IsDefaultRecvStream(ssrc)) { |
| + // If this stream was previously received unsignaled, remove it first. |
| + if (TryDeregisterUnsignaledRecvStream(ssrc)) { |
| RemoveRecvStream(ssrc); |
| } |
| @@ -2342,10 +2343,7 @@ bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32_t ssrc) { |
| return false; |
| } |
| - // Deregister default channel, if that's the one being destroyed. |
| - if (IsDefaultRecvStream(ssrc)) { |
| - default_recv_ssrc_ = -1; |
| - } |
| + TryDeregisterUnsignaledRecvStream(ssrc); |
| const int channel = it->second->channel(); |
| @@ -2405,21 +2403,21 @@ int WebRtcVoiceMediaChannel::GetOutputLevel() { |
| bool WebRtcVoiceMediaChannel::SetOutputVolume(uint32_t ssrc, double volume) { |
| RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| + std::vector<uint32_t> ssrcs(1, ssrc); |
| if (ssrc == 0) { |
| default_recv_volume_ = volume; |
| - if (default_recv_ssrc_ == -1) { |
| - return true; |
| - } |
| - ssrc = static_cast<uint32_t>(default_recv_ssrc_); |
| + ssrcs = unsignaled_recv_ssrcs_; |
| } |
| - const auto it = recv_streams_.find(ssrc); |
| - if (it == recv_streams_.end()) { |
| - LOG(LS_WARNING) << "SetOutputVolume: no recv stream" << ssrc; |
| - return false; |
| + for (uint32_t ssrc : ssrcs) { |
| + const auto it = recv_streams_.find(ssrc); |
| + if (it == recv_streams_.end()) { |
| + LOG(LS_WARNING) << "SetOutputVolume: no recv stream " << ssrc; |
| + return false; |
| + } |
| + it->second->SetOutputVolume(volume); |
| + LOG(LS_INFO) << "SetOutputVolume() to " << volume |
| + << " for recv stream with ssrc " << ssrc; |
| } |
| - it->second->SetOutputVolume(volume); |
| - LOG(LS_INFO) << "SetOutputVolume() to " << volume |
| - << " for recv stream with ssrc " << ssrc; |
| return true; |
| } |
| @@ -2470,35 +2468,44 @@ void WebRtcVoiceMediaChannel::OnPacketReceived( |
| return; |
| } |
| - // Create a default receive stream for this unsignalled and previously not |
| - // received ssrc. If there already is a default receive stream, delete it. |
| + // Create an unsignaled receive stream for this previously not received ssrc. |
| + // If there already is N unsignaled receive streams, delete the oldest. |
| // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5208 |
| uint32_t ssrc = 0; |
| if (!GetRtpSsrc(packet->cdata(), packet->size(), &ssrc)) { |
| return; |
| } |
| + RTC_DCHECK(std::find(unsignaled_recv_ssrcs_.begin(), |
| + unsignaled_recv_ssrcs_.end(), ssrc) == unsignaled_recv_ssrcs_.end()); |
| + // Add new stream. |
| StreamParams sp; |
| sp.ssrcs.push_back(ssrc); |
| - LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; |
| + LOG(LS_INFO) << "Creating unsignaled receive stream for SSRC=" << ssrc; |
| if (!AddRecvStream(sp)) { |
| - LOG(LS_WARNING) << "Could not create default receive stream."; |
| + LOG(LS_WARNING) << "Could not create unsignaled receive stream."; |
| return; |
| } |
| - if (default_recv_ssrc_ != -1) { |
| - LOG(LS_INFO) << "Removing default receive stream with ssrc " |
| - << default_recv_ssrc_; |
| - RTC_DCHECK_NE(ssrc, default_recv_ssrc_); |
| - RemoveRecvStream(default_recv_ssrc_); |
| + unsignaled_recv_ssrcs_.push_back(ssrc); |
| + |
| + // Remove oldest unsignaled stream, if we have too many. |
| + if (unsignaled_recv_ssrcs_.size() > kMaxUnsignaledRecvStreams) { |
| + uint32_t remove_ssrc = unsignaled_recv_ssrcs_.front(); |
| + LOG(LS_INFO) << "Removing unsignaled receive stream with SSRC=" |
| + << remove_ssrc; |
| + RemoveRecvStream(remove_ssrc); |
| } |
| - default_recv_ssrc_ = ssrc; |
| + RTC_DCHECK_GE(kMaxUnsignaledRecvStreams, unsignaled_recv_ssrcs_.size()); |
| + |
| + SetOutputVolume(ssrc, default_recv_volume_); |
| - SetOutputVolume(default_recv_ssrc_, default_recv_volume_); |
| - if (default_sink_) { |
| + // 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
|
| + if (default_sink_ && unsignaled_recv_ssrcs_.size() == 1) { |
| std::unique_ptr<webrtc::AudioSinkInterface> proxy_sink( |
| new ProxySink(default_sink_.get())); |
| - SetRawAudioSink(default_recv_ssrc_, std::move(proxy_sink)); |
| + SetRawAudioSink(ssrc, std::move(proxy_sink)); |
| } |
| + |
| delivery_result = call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, |
| packet->cdata(), |
| packet->size(), |
| @@ -2663,17 +2670,17 @@ void WebRtcVoiceMediaChannel::SetRawAudioSink( |
| LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::SetRawAudioSink: ssrc:" << ssrc |
| << " " << (sink ? "(ptr)" : "NULL"); |
| if (ssrc == 0) { |
| - if (default_recv_ssrc_ != -1) { |
| + if (unsignaled_recv_ssrcs_.size() == 1) { |
| std::unique_ptr<webrtc::AudioSinkInterface> proxy_sink( |
| sink ? new ProxySink(sink.get()) : nullptr); |
| - SetRawAudioSink(default_recv_ssrc_, std::move(proxy_sink)); |
| + SetRawAudioSink(unsignaled_recv_ssrcs_.front(), std::move(proxy_sink)); |
| } |
| default_sink_ = std::move(sink); |
| return; |
| } |
| const auto it = recv_streams_.find(ssrc); |
| if (it == recv_streams_.end()) { |
| - LOG(LS_WARNING) << "SetRawAudioSink: no recv stream" << ssrc; |
| + LOG(LS_WARNING) << "SetRawAudioSink: no recv stream " << ssrc; |
| return; |
| } |
| it->second->SetRawAudioSink(std::move(sink)); |
| @@ -2702,6 +2709,18 @@ int WebRtcVoiceMediaChannel::GetSendChannelId(uint32_t ssrc) const { |
| } |
| return -1; |
| } |
| + |
| +bool WebRtcVoiceMediaChannel::TryDeregisterUnsignaledRecvStream(uint32_t ssrc) { |
| + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| + auto it = std::find(unsignaled_recv_ssrcs_.begin(), |
| + unsignaled_recv_ssrcs_.end(), |
| + ssrc); |
| + if (it != unsignaled_recv_ssrcs_.end()) { |
| + unsignaled_recv_ssrcs_.erase(it); |
| + return true; |
| + } |
| + return false; |
| +} |
| } // namespace cricket |
| #endif // HAVE_WEBRTC_VOICE |