Index: talk/media/webrtc/webrtcvoiceengine.cc |
diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc |
index a7e1a439bd091a60d9951168d69bfd5e0ba11028..c13b22933a323f99eba553d5b84229cf992417b3 100644 |
--- a/talk/media/webrtc/webrtcvoiceengine.cc |
+++ b/talk/media/webrtc/webrtcvoiceengine.cc |
@@ -396,6 +396,19 @@ webrtc::AudioState::Config MakeAudioStateConfig(VoEWrapper* voe_wrapper) { |
return config; |
} |
+std::vector<webrtc::RtpExtension> FindAudioRtpHeaderExtensions( |
+ const std::vector<RtpHeaderExtension>& extensions) { |
+ std::vector<webrtc::RtpExtension> result; |
+ for (const auto& extension : extensions) { |
+ if (extension.uri == kRtpAbsoluteSenderTimeHeaderExtension || |
+ extension.uri == kRtpAudioLevelHeaderExtension) { |
+ result.push_back({extension.uri, extension.id}); |
+ } else { |
+ LOG(LS_WARNING) << "Unsupported RTP extension: " << extension.ToString(); |
+ } |
+ } |
+ return result; |
+} |
} // namespace { |
WebRtcVoiceEngine::WebRtcVoiceEngine() |
@@ -1337,27 +1350,49 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
: public AudioRenderer::Sink { |
public: |
WebRtcAudioSendStream(int ch, webrtc::AudioTransport* voe_audio_transport, |
- uint32_t ssrc, webrtc::Call* call) |
+ uint32_t ssrc, const std::string& c_name, |
+ const std::vector<webrtc::RtpExtension>& extensions, |
+ webrtc::Call* call) |
: channel_(ch), |
voe_audio_transport_(voe_audio_transport), |
- call_(call) { |
+ call_(call), |
+ config_(nullptr) { |
RTC_DCHECK_GE(ch, 0); |
// TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: |
// RTC_DCHECK(voe_audio_transport); |
RTC_DCHECK(call); |
audio_capture_thread_checker_.DetachFromThread(); |
- webrtc::AudioSendStream::Config config(nullptr); |
- config.voe_channel_id = channel_; |
- config.rtp.ssrc = ssrc; |
- stream_ = call_->CreateAudioSendStream(config); |
- RTC_DCHECK(stream_); |
+ config_.rtp.ssrc = ssrc; |
+ config_.rtp.c_name = c_name; |
+ config_.voe_channel_id = ch; |
+ RecreateAudioSendStream(extensions); |
} |
+ |
~WebRtcAudioSendStream() override { |
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
Stop(); |
call_->DestroyAudioSendStream(stream_); |
} |
+ void RecreateAudioSendStream( |
+ const std::vector<webrtc::RtpExtension>& extensions) { |
+ RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
+ if (stream_) { |
+ call_->DestroyAudioSendStream(stream_); |
+ stream_ = nullptr; |
+ } |
+ config_.rtp.extensions = extensions; |
+ RTC_DCHECK(!stream_); |
+ stream_ = call_->CreateAudioSendStream(config_); |
+ RTC_CHECK(stream_); |
+ } |
+ |
+ webrtc::AudioSendStream::Stats GetStats() const { |
+ RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
+ RTC_DCHECK(stream_); |
+ return stream_->GetStats(); |
+ } |
+ |
// Starts the rendering by setting a sink to the renderer to get data |
// callback. |
// This method is called on the libjingle worker thread. |
@@ -1373,11 +1408,6 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
renderer_ = renderer; |
} |
- webrtc::AudioSendStream::Stats GetStats() const { |
- RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
- return stream_->GetStats(); |
- } |
- |
// Stops rendering by setting the sink of the renderer to nullptr. No data |
// callback will be received after this method. |
// This method is called on the libjingle worker thread. |
@@ -1428,6 +1458,9 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
const int channel_ = -1; |
webrtc::AudioTransport* const voe_audio_transport_ = nullptr; |
webrtc::Call* call_ = nullptr; |
+ webrtc::AudioSendStream::Config config_; |
+ // The stream is owned by WebRtcAudioSendStream and may be reallocated if |
+ // configuration changes. |
webrtc::AudioSendStream* stream_ = nullptr; |
// Raw pointer to AudioRenderer owned by LocalAudioTrackHandler. |
@@ -1486,10 +1519,24 @@ bool WebRtcVoiceMediaChannel::SetSendParameters( |
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
// TODO(pthatcher): Refactor this to be more clean now that we have |
// all the information at once. |
- return (SetSendCodecs(params.codecs) && |
- SetSendRtpHeaderExtensions(params.extensions) && |
- SetMaxSendBandwidth(params.max_bandwidth_bps) && |
- SetOptions(params.options)); |
+ |
+ if (!SetSendCodecs(params.codecs)) { |
+ return false; |
+ } |
+ |
+ std::vector<webrtc::RtpExtension> send_rtp_extensions = |
+ FindAudioRtpHeaderExtensions(params.extensions); |
+ if (send_rtp_extensions_ != send_rtp_extensions) { |
+ send_rtp_extensions_.swap(send_rtp_extensions); |
+ for (auto& it : send_streams_) { |
+ it.second->RecreateAudioSendStream(send_rtp_extensions_); |
+ } |
+ } |
+ |
+ if (!SetMaxSendBandwidth(params.max_bandwidth_bps)) { |
+ return false; |
+ } |
+ return SetOptions(params.options); |
} |
bool WebRtcVoiceMediaChannel::SetRecvParameters( |
@@ -1870,26 +1917,8 @@ bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions( |
receive_extensions_ = extensions; |
// Recreate AudioReceiveStream:s. |
- { |
- std::vector<webrtc::RtpExtension> exts; |
- |
- const RtpHeaderExtension* audio_level_extension = |
- FindHeaderExtension(extensions, kRtpAudioLevelHeaderExtension); |
- if (audio_level_extension) { |
- exts.push_back({ |
- kRtpAudioLevelHeaderExtension, audio_level_extension->id}); |
- } |
- |
- const RtpHeaderExtension* send_time_extension = |
- FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); |
- if (send_time_extension) { |
- exts.push_back({ |
- kRtpAbsoluteSenderTimeHeaderExtension, send_time_extension->id}); |
- } |
- |
- recv_rtp_extensions_.swap(exts); |
- RecreateAudioReceiveStreams(); |
- } |
+ recv_rtp_extensions_ = FindAudioRtpHeaderExtensions(extensions); |
+ RecreateAudioReceiveStreams(); |
return true; |
} |
@@ -1915,45 +1944,6 @@ bool WebRtcVoiceMediaChannel::SetChannelRecvRtpHeaderExtensions( |
return true; |
} |
-bool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions( |
- const std::vector<RtpHeaderExtension>& extensions) { |
- RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
- if (send_extensions_ == extensions) { |
- return true; |
- } |
- |
- for (const auto& ch : send_streams_) { |
- if (!SetChannelSendRtpHeaderExtensions(ch.second->channel(), extensions)) { |
- return false; |
- } |
- } |
- |
- send_extensions_ = extensions; |
- return true; |
-} |
- |
-bool WebRtcVoiceMediaChannel::SetChannelSendRtpHeaderExtensions( |
- int channel_id, const std::vector<RtpHeaderExtension>& extensions) { |
- const RtpHeaderExtension* audio_level_extension = |
- FindHeaderExtension(extensions, kRtpAudioLevelHeaderExtension); |
- |
- if (!SetHeaderExtension( |
- &webrtc::VoERTP_RTCP::SetSendAudioLevelIndicationStatus, channel_id, |
- audio_level_extension)) { |
- return false; |
- } |
- |
- const RtpHeaderExtension* send_time_extension = |
- FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); |
- if (!SetHeaderExtension( |
- &webrtc::VoERTP_RTCP::SetSendAbsoluteSenderTimeStatus, channel_id, |
- send_time_extension)) { |
- return false; |
- } |
- |
- return true; |
-} |
- |
bool WebRtcVoiceMediaChannel::SetPlayout(bool playout) { |
desired_playout_ = playout; |
return ChangePlayout(desired_playout_); |
@@ -2107,33 +2097,12 @@ bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { |
return false; |
} |
- // Enable RTCP (for quality stats and feedback messages). |
- if (engine()->voe()->rtp()->SetRTCPStatus(channel, true) == -1) { |
- LOG_RTCERR2(SetRTCPStatus, channel, 1); |
- } |
- |
- SetChannelSendRtpHeaderExtensions(channel, send_extensions_); |
- |
- // Set the local (send) SSRC. |
- if (engine()->voe()->rtp()->SetLocalSSRC(channel, ssrc) == -1) { |
- LOG_RTCERR2(SetLocalSSRC, channel, ssrc); |
- DeleteChannel(channel); |
- return false; |
- } |
- |
- if (engine()->voe()->rtp()->SetRTCP_CNAME(channel, sp.cname.c_str()) == -1) { |
- LOG_RTCERR2(SetRTCP_CNAME, channel, sp.cname); |
- DeleteChannel(channel); |
- return false; |
- } |
- |
// Save the channel to send_streams_, so that RemoveSendStream() can still |
// delete the channel in case failure happens below. |
webrtc::AudioTransport* audio_transport = |
engine()->voe()->base()->audio_transport(); |
- send_streams_.insert( |
- std::make_pair(ssrc, |
- new WebRtcAudioSendStream(channel, audio_transport, ssrc, call_))); |
+ send_streams_.insert(std::make_pair(ssrc, new WebRtcAudioSendStream( |
+ channel, audio_transport, ssrc, sp.cname, send_rtp_extensions_, call_))); |
// Set the current codecs to be used for the new channel. We need to do this |
// after adding the channel to send_channels_, because of how max bitrate is |
@@ -2165,6 +2134,8 @@ bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { |
bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32_t ssrc) { |
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
+ LOG(LS_INFO) << "RemoveSendStream: " << ssrc; |
+ |
auto it = send_streams_.find(ssrc); |
if (it == send_streams_.end()) { |
LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc |