blob: 58cb18c6cd2734e5bc37df470c5a3ba121abd401 [file] [log] [blame]
deadbeef6979b022015-09-24 16:47:53 -07001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2015 The WebRTC project authors. All Rights Reserved.
deadbeef6979b022015-09-24 16:47:53 -07003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * 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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
deadbeef6979b022015-09-24 16:47:53 -07009 */
10
Henrik Kjellander15583c12016-02-10 10:53:12 +010011#include "webrtc/api/rtpsender.h"
deadbeef6979b022015-09-24 16:47:53 -070012
Henrik Kjellander15583c12016-02-10 10:53:12 +010013#include "webrtc/api/localaudiosource.h"
perkj9e083d22016-03-20 09:38:40 -070014#include "webrtc/api/mediastreaminterface.h"
deadbeeffac06552015-11-25 11:26:01 -080015#include "webrtc/base/helpers.h"
Peter Boströmdabc9442016-04-11 11:45:14 +020016#include "webrtc/base/trace_event.h"
deadbeef70ab1a12015-09-28 16:53:55 -070017
18namespace webrtc {
19
20LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(nullptr) {}
21
22LocalAudioSinkAdapter::~LocalAudioSinkAdapter() {
23 rtc::CritScope lock(&lock_);
24 if (sink_)
25 sink_->OnClose();
26}
27
28void LocalAudioSinkAdapter::OnData(const void* audio_data,
29 int bits_per_sample,
30 int sample_rate,
Peter Kasting69558702016-01-12 16:26:35 -080031 size_t number_of_channels,
deadbeef70ab1a12015-09-28 16:53:55 -070032 size_t number_of_frames) {
33 rtc::CritScope lock(&lock_);
34 if (sink_) {
35 sink_->OnData(audio_data, bits_per_sample, sample_rate, number_of_channels,
36 number_of_frames);
37 }
38}
39
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -080040void LocalAudioSinkAdapter::SetSink(cricket::AudioSource::Sink* sink) {
deadbeef70ab1a12015-09-28 16:53:55 -070041 rtc::CritScope lock(&lock_);
42 ASSERT(!sink || !sink_);
43 sink_ = sink;
44}
45
46AudioRtpSender::AudioRtpSender(AudioTrackInterface* track,
deadbeeffac06552015-11-25 11:26:01 -080047 const std::string& stream_id,
48 AudioProviderInterface* provider,
49 StatsCollector* stats)
deadbeef70ab1a12015-09-28 16:53:55 -070050 : id_(track->id()),
deadbeeffac06552015-11-25 11:26:01 -080051 stream_id_(stream_id),
deadbeef5def7b92015-11-20 11:43:22 -080052 provider_(provider),
deadbeeffac06552015-11-25 11:26:01 -080053 stats_(stats),
54 track_(track),
deadbeef70ab1a12015-09-28 16:53:55 -070055 cached_track_enabled_(track->enabled()),
56 sink_adapter_(new LocalAudioSinkAdapter()) {
deadbeeffac06552015-11-25 11:26:01 -080057 RTC_DCHECK(provider != nullptr);
deadbeef70ab1a12015-09-28 16:53:55 -070058 track_->RegisterObserver(this);
59 track_->AddSink(sink_adapter_.get());
deadbeef70ab1a12015-09-28 16:53:55 -070060}
61
deadbeefe1f9d832016-01-14 15:35:42 -080062AudioRtpSender::AudioRtpSender(AudioTrackInterface* track,
63 AudioProviderInterface* provider,
64 StatsCollector* stats)
65 : id_(track->id()),
66 stream_id_(rtc::CreateRandomUuid()),
67 provider_(provider),
68 stats_(stats),
69 track_(track),
70 cached_track_enabled_(track->enabled()),
71 sink_adapter_(new LocalAudioSinkAdapter()) {
72 RTC_DCHECK(provider != nullptr);
73 track_->RegisterObserver(this);
74 track_->AddSink(sink_adapter_.get());
75}
76
deadbeeffac06552015-11-25 11:26:01 -080077AudioRtpSender::AudioRtpSender(AudioProviderInterface* provider,
78 StatsCollector* stats)
79 : id_(rtc::CreateRandomUuid()),
80 stream_id_(rtc::CreateRandomUuid()),
81 provider_(provider),
82 stats_(stats),
83 sink_adapter_(new LocalAudioSinkAdapter()) {}
84
deadbeef70ab1a12015-09-28 16:53:55 -070085AudioRtpSender::~AudioRtpSender() {
deadbeef70ab1a12015-09-28 16:53:55 -070086 Stop();
87}
88
89void AudioRtpSender::OnChanged() {
Peter Boströmdabc9442016-04-11 11:45:14 +020090 TRACE_EVENT0("webrtc", "AudioRtpSender::OnChanged");
deadbeeffac06552015-11-25 11:26:01 -080091 RTC_DCHECK(!stopped_);
deadbeef70ab1a12015-09-28 16:53:55 -070092 if (cached_track_enabled_ != track_->enabled()) {
93 cached_track_enabled_ = track_->enabled();
deadbeeffac06552015-11-25 11:26:01 -080094 if (can_send_track()) {
95 SetAudioSend();
96 }
deadbeef70ab1a12015-09-28 16:53:55 -070097 }
98}
99
100bool AudioRtpSender::SetTrack(MediaStreamTrackInterface* track) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200101 TRACE_EVENT0("webrtc", "AudioRtpSender::SetTrack");
deadbeeffac06552015-11-25 11:26:01 -0800102 if (stopped_) {
103 LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
104 return false;
105 }
106 if (track && track->kind() != MediaStreamTrackInterface::kAudioKind) {
deadbeef70ab1a12015-09-28 16:53:55 -0700107 LOG(LS_ERROR) << "SetTrack called on audio RtpSender with " << track->kind()
108 << " track.";
109 return false;
110 }
111 AudioTrackInterface* audio_track = static_cast<AudioTrackInterface*>(track);
112
113 // Detach from old track.
deadbeeffac06552015-11-25 11:26:01 -0800114 if (track_) {
115 track_->RemoveSink(sink_adapter_.get());
116 track_->UnregisterObserver(this);
117 }
118
119 if (can_send_track() && stats_) {
120 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
121 }
deadbeef70ab1a12015-09-28 16:53:55 -0700122
123 // Attach to new track.
deadbeeffac06552015-11-25 11:26:01 -0800124 bool prev_can_send_track = can_send_track();
deadbeef70ab1a12015-09-28 16:53:55 -0700125 track_ = audio_track;
deadbeeffac06552015-11-25 11:26:01 -0800126 if (track_) {
127 cached_track_enabled_ = track_->enabled();
128 track_->RegisterObserver(this);
129 track_->AddSink(sink_adapter_.get());
130 }
131
132 // Update audio provider.
133 if (can_send_track()) {
134 SetAudioSend();
135 if (stats_) {
136 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
137 }
138 } else if (prev_can_send_track) {
139 cricket::AudioOptions options;
140 provider_->SetAudioSend(ssrc_, false, options, nullptr);
141 }
deadbeef70ab1a12015-09-28 16:53:55 -0700142 return true;
143}
144
deadbeeffac06552015-11-25 11:26:01 -0800145void AudioRtpSender::SetSsrc(uint32_t ssrc) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200146 TRACE_EVENT0("webrtc", "AudioRtpSender::SetSsrc");
deadbeeffac06552015-11-25 11:26:01 -0800147 if (stopped_ || ssrc == ssrc_) {
148 return;
149 }
150 // If we are already sending with a particular SSRC, stop sending.
151 if (can_send_track()) {
152 cricket::AudioOptions options;
153 provider_->SetAudioSend(ssrc_, false, options, nullptr);
154 if (stats_) {
155 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
156 }
157 }
158 ssrc_ = ssrc;
159 if (can_send_track()) {
160 SetAudioSend();
161 if (stats_) {
162 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
163 }
164 }
165}
166
deadbeef70ab1a12015-09-28 16:53:55 -0700167void AudioRtpSender::Stop() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200168 TRACE_EVENT0("webrtc", "AudioRtpSender::Stop");
deadbeef70ab1a12015-09-28 16:53:55 -0700169 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800170 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700171 return;
172 }
deadbeeffac06552015-11-25 11:26:01 -0800173 if (track_) {
174 track_->RemoveSink(sink_adapter_.get());
175 track_->UnregisterObserver(this);
176 }
177 if (can_send_track()) {
178 cricket::AudioOptions options;
179 provider_->SetAudioSend(ssrc_, false, options, nullptr);
180 if (stats_) {
181 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
182 }
183 }
184 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700185}
186
deadbeeffac06552015-11-25 11:26:01 -0800187void AudioRtpSender::SetAudioSend() {
188 RTC_DCHECK(!stopped_ && can_send_track());
deadbeef70ab1a12015-09-28 16:53:55 -0700189 cricket::AudioOptions options;
Tommi3c169782016-01-21 16:12:17 +0100190#if !defined(WEBRTC_CHROMIUM_BUILD)
191 // TODO(tommi): Remove this hack when we move CreateAudioSource out of
192 // PeerConnection. This is a bit of a strange way to apply local audio
193 // options since it is also applied to all streams/channels, local or remote.
tommi6eca7e32015-12-15 04:27:11 -0800194 if (track_->enabled() && track_->GetSource() &&
195 !track_->GetSource()->remote()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700196 // TODO(xians): Remove this static_cast since we should be able to connect
deadbeeffac06552015-11-25 11:26:01 -0800197 // a remote audio track to a peer connection.
deadbeef70ab1a12015-09-28 16:53:55 -0700198 options = static_cast<LocalAudioSource*>(track_->GetSource())->options();
199 }
Tommi3c169782016-01-21 16:12:17 +0100200#endif
deadbeef70ab1a12015-09-28 16:53:55 -0700201
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800202 cricket::AudioSource* source = sink_adapter_.get();
203 ASSERT(source != nullptr);
204 provider_->SetAudioSend(ssrc_, track_->enabled(), options, source);
deadbeef70ab1a12015-09-28 16:53:55 -0700205}
206
skvladdc1c62c2016-03-16 19:07:43 -0700207RtpParameters AudioRtpSender::GetParameters() const {
208 return provider_->GetAudioRtpParameters(ssrc_);
209}
210
211bool AudioRtpSender::SetParameters(const RtpParameters& parameters) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200212 TRACE_EVENT0("webrtc", "AudioRtpSender::SetParameters");
skvladdc1c62c2016-03-16 19:07:43 -0700213 return provider_->SetAudioRtpParameters(ssrc_, parameters);
214}
215
deadbeef70ab1a12015-09-28 16:53:55 -0700216VideoRtpSender::VideoRtpSender(VideoTrackInterface* track,
deadbeeffac06552015-11-25 11:26:01 -0800217 const std::string& stream_id,
deadbeef70ab1a12015-09-28 16:53:55 -0700218 VideoProviderInterface* provider)
219 : id_(track->id()),
deadbeeffac06552015-11-25 11:26:01 -0800220 stream_id_(stream_id),
deadbeef5def7b92015-11-20 11:43:22 -0800221 provider_(provider),
deadbeeffac06552015-11-25 11:26:01 -0800222 track_(track),
deadbeef70ab1a12015-09-28 16:53:55 -0700223 cached_track_enabled_(track->enabled()) {
deadbeeffac06552015-11-25 11:26:01 -0800224 RTC_DCHECK(provider != nullptr);
deadbeef70ab1a12015-09-28 16:53:55 -0700225 track_->RegisterObserver(this);
deadbeef70ab1a12015-09-28 16:53:55 -0700226}
227
deadbeefe1f9d832016-01-14 15:35:42 -0800228VideoRtpSender::VideoRtpSender(VideoTrackInterface* track,
229 VideoProviderInterface* provider)
230 : id_(track->id()),
231 stream_id_(rtc::CreateRandomUuid()),
232 provider_(provider),
233 track_(track),
234 cached_track_enabled_(track->enabled()) {
235 RTC_DCHECK(provider != nullptr);
236 track_->RegisterObserver(this);
237}
238
deadbeeffac06552015-11-25 11:26:01 -0800239VideoRtpSender::VideoRtpSender(VideoProviderInterface* provider)
240 : id_(rtc::CreateRandomUuid()),
241 stream_id_(rtc::CreateRandomUuid()),
242 provider_(provider) {}
243
deadbeef70ab1a12015-09-28 16:53:55 -0700244VideoRtpSender::~VideoRtpSender() {
deadbeef70ab1a12015-09-28 16:53:55 -0700245 Stop();
246}
247
248void VideoRtpSender::OnChanged() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200249 TRACE_EVENT0("webrtc", "VideoRtpSender::OnChanged");
deadbeeffac06552015-11-25 11:26:01 -0800250 RTC_DCHECK(!stopped_);
deadbeef70ab1a12015-09-28 16:53:55 -0700251 if (cached_track_enabled_ != track_->enabled()) {
252 cached_track_enabled_ = track_->enabled();
deadbeeffac06552015-11-25 11:26:01 -0800253 if (can_send_track()) {
254 SetVideoSend();
255 }
deadbeef70ab1a12015-09-28 16:53:55 -0700256 }
257}
258
259bool VideoRtpSender::SetTrack(MediaStreamTrackInterface* track) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200260 TRACE_EVENT0("webrtc", "VideoRtpSender::SetTrack");
deadbeeffac06552015-11-25 11:26:01 -0800261 if (stopped_) {
262 LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
263 return false;
264 }
265 if (track && track->kind() != MediaStreamTrackInterface::kVideoKind) {
deadbeef70ab1a12015-09-28 16:53:55 -0700266 LOG(LS_ERROR) << "SetTrack called on video RtpSender with " << track->kind()
267 << " track.";
268 return false;
269 }
270 VideoTrackInterface* video_track = static_cast<VideoTrackInterface*>(track);
271
272 // Detach from old track.
deadbeeffac06552015-11-25 11:26:01 -0800273 if (track_) {
274 track_->UnregisterObserver(this);
275 }
deadbeef70ab1a12015-09-28 16:53:55 -0700276
277 // Attach to new track.
deadbeeffac06552015-11-25 11:26:01 -0800278 bool prev_can_send_track = can_send_track();
deadbeef70ab1a12015-09-28 16:53:55 -0700279 track_ = video_track;
deadbeeffac06552015-11-25 11:26:01 -0800280 if (track_) {
281 cached_track_enabled_ = track_->enabled();
282 track_->RegisterObserver(this);
283 }
284
285 // Update video provider.
286 if (can_send_track()) {
deadbeeffac06552015-11-25 11:26:01 -0800287 // TODO(deadbeef): If SetTrack is called with a disabled track, and the
288 // previous track was enabled, this could cause a frame from the new track
nisse2ded9b12016-04-08 02:23:55 -0700289 // to slip out. Really, what we need is for SetSource and SetVideoSend
deadbeeffac06552015-11-25 11:26:01 -0800290 // to be combined into one atomic operation, all the way down to
291 // WebRtcVideoSendStream.
nisse2ded9b12016-04-08 02:23:55 -0700292
293 provider_->SetSource(ssrc_, track_);
deadbeeffac06552015-11-25 11:26:01 -0800294 SetVideoSend();
295 } else if (prev_can_send_track) {
nisse2ded9b12016-04-08 02:23:55 -0700296 provider_->SetSource(ssrc_, nullptr);
deadbeeffac06552015-11-25 11:26:01 -0800297 provider_->SetVideoSend(ssrc_, false, nullptr);
298 }
deadbeef70ab1a12015-09-28 16:53:55 -0700299 return true;
300}
301
deadbeeffac06552015-11-25 11:26:01 -0800302void VideoRtpSender::SetSsrc(uint32_t ssrc) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200303 TRACE_EVENT0("webrtc", "VideoRtpSender::SetSsrc");
deadbeeffac06552015-11-25 11:26:01 -0800304 if (stopped_ || ssrc == ssrc_) {
305 return;
306 }
307 // If we are already sending with a particular SSRC, stop sending.
308 if (can_send_track()) {
nisse2ded9b12016-04-08 02:23:55 -0700309 provider_->SetSource(ssrc_, nullptr);
deadbeeffac06552015-11-25 11:26:01 -0800310 provider_->SetVideoSend(ssrc_, false, nullptr);
311 }
312 ssrc_ = ssrc;
313 if (can_send_track()) {
nisse2ded9b12016-04-08 02:23:55 -0700314 provider_->SetSource(ssrc_, track_);
deadbeeffac06552015-11-25 11:26:01 -0800315 SetVideoSend();
316 }
317}
318
deadbeef70ab1a12015-09-28 16:53:55 -0700319void VideoRtpSender::Stop() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200320 TRACE_EVENT0("webrtc", "VideoRtpSender::Stop");
deadbeef70ab1a12015-09-28 16:53:55 -0700321 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800322 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700323 return;
324 }
deadbeeffac06552015-11-25 11:26:01 -0800325 if (track_) {
326 track_->UnregisterObserver(this);
327 }
328 if (can_send_track()) {
nisse2ded9b12016-04-08 02:23:55 -0700329 provider_->SetSource(ssrc_, nullptr);
deadbeeffac06552015-11-25 11:26:01 -0800330 provider_->SetVideoSend(ssrc_, false, nullptr);
331 }
332 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700333}
334
deadbeeffac06552015-11-25 11:26:01 -0800335void VideoRtpSender::SetVideoSend() {
336 RTC_DCHECK(!stopped_ && can_send_track());
perkj0d3eef22016-03-09 02:39:17 +0100337 cricket::VideoOptions options;
perkja3ede6c2016-03-08 01:27:48 +0100338 VideoTrackSourceInterface* source = track_->GetSource();
perkj0d3eef22016-03-09 02:39:17 +0100339 if (source) {
340 options.is_screencast = rtc::Optional<bool>(source->is_screencast());
Perc0d31e92016-03-31 17:23:39 +0200341 options.video_noise_reduction = source->needs_denoising();
deadbeef70ab1a12015-09-28 16:53:55 -0700342 }
perkj0d3eef22016-03-09 02:39:17 +0100343 provider_->SetVideoSend(ssrc_, track_->enabled(), &options);
deadbeef70ab1a12015-09-28 16:53:55 -0700344}
345
skvladdc1c62c2016-03-16 19:07:43 -0700346RtpParameters VideoRtpSender::GetParameters() const {
347 return provider_->GetVideoRtpParameters(ssrc_);
348}
349
350bool VideoRtpSender::SetParameters(const RtpParameters& parameters) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200351 TRACE_EVENT0("webrtc", "VideoRtpSender::SetParameters");
skvladdc1c62c2016-03-16 19:07:43 -0700352 return provider_->SetVideoRtpParameters(ssrc_, parameters);
353}
354
deadbeef70ab1a12015-09-28 16:53:55 -0700355} // namespace webrtc