blob: 9c6dfb8092844c9fe7820cbef485b713f2e825bc [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"
14#include "webrtc/api/videosourceinterface.h"
deadbeeffac06552015-11-25 11:26:01 -080015#include "webrtc/base/helpers.h"
deadbeef70ab1a12015-09-28 16:53:55 -070016
17namespace webrtc {
18
19LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(nullptr) {}
20
21LocalAudioSinkAdapter::~LocalAudioSinkAdapter() {
22 rtc::CritScope lock(&lock_);
23 if (sink_)
24 sink_->OnClose();
25}
26
27void LocalAudioSinkAdapter::OnData(const void* audio_data,
28 int bits_per_sample,
29 int sample_rate,
Peter Kasting69558702016-01-12 16:26:35 -080030 size_t number_of_channels,
deadbeef70ab1a12015-09-28 16:53:55 -070031 size_t number_of_frames) {
32 rtc::CritScope lock(&lock_);
33 if (sink_) {
34 sink_->OnData(audio_data, bits_per_sample, sample_rate, number_of_channels,
35 number_of_frames);
36 }
37}
38
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -080039void LocalAudioSinkAdapter::SetSink(cricket::AudioSource::Sink* sink) {
deadbeef70ab1a12015-09-28 16:53:55 -070040 rtc::CritScope lock(&lock_);
41 ASSERT(!sink || !sink_);
42 sink_ = sink;
43}
44
45AudioRtpSender::AudioRtpSender(AudioTrackInterface* track,
deadbeeffac06552015-11-25 11:26:01 -080046 const std::string& stream_id,
47 AudioProviderInterface* provider,
48 StatsCollector* stats)
deadbeef70ab1a12015-09-28 16:53:55 -070049 : id_(track->id()),
deadbeeffac06552015-11-25 11:26:01 -080050 stream_id_(stream_id),
deadbeef5def7b92015-11-20 11:43:22 -080051 provider_(provider),
deadbeeffac06552015-11-25 11:26:01 -080052 stats_(stats),
53 track_(track),
deadbeef70ab1a12015-09-28 16:53:55 -070054 cached_track_enabled_(track->enabled()),
55 sink_adapter_(new LocalAudioSinkAdapter()) {
deadbeeffac06552015-11-25 11:26:01 -080056 RTC_DCHECK(provider != nullptr);
deadbeef70ab1a12015-09-28 16:53:55 -070057 track_->RegisterObserver(this);
58 track_->AddSink(sink_adapter_.get());
deadbeef70ab1a12015-09-28 16:53:55 -070059}
60
deadbeefe1f9d832016-01-14 15:35:42 -080061AudioRtpSender::AudioRtpSender(AudioTrackInterface* track,
62 AudioProviderInterface* provider,
63 StatsCollector* stats)
64 : id_(track->id()),
65 stream_id_(rtc::CreateRandomUuid()),
66 provider_(provider),
67 stats_(stats),
68 track_(track),
69 cached_track_enabled_(track->enabled()),
70 sink_adapter_(new LocalAudioSinkAdapter()) {
71 RTC_DCHECK(provider != nullptr);
72 track_->RegisterObserver(this);
73 track_->AddSink(sink_adapter_.get());
74}
75
deadbeeffac06552015-11-25 11:26:01 -080076AudioRtpSender::AudioRtpSender(AudioProviderInterface* provider,
77 StatsCollector* stats)
78 : id_(rtc::CreateRandomUuid()),
79 stream_id_(rtc::CreateRandomUuid()),
80 provider_(provider),
81 stats_(stats),
82 sink_adapter_(new LocalAudioSinkAdapter()) {}
83
deadbeef70ab1a12015-09-28 16:53:55 -070084AudioRtpSender::~AudioRtpSender() {
deadbeef70ab1a12015-09-28 16:53:55 -070085 Stop();
86}
87
88void AudioRtpSender::OnChanged() {
deadbeeffac06552015-11-25 11:26:01 -080089 RTC_DCHECK(!stopped_);
deadbeef70ab1a12015-09-28 16:53:55 -070090 if (cached_track_enabled_ != track_->enabled()) {
91 cached_track_enabled_ = track_->enabled();
deadbeeffac06552015-11-25 11:26:01 -080092 if (can_send_track()) {
93 SetAudioSend();
94 }
deadbeef70ab1a12015-09-28 16:53:55 -070095 }
96}
97
98bool AudioRtpSender::SetTrack(MediaStreamTrackInterface* track) {
deadbeeffac06552015-11-25 11:26:01 -080099 if (stopped_) {
100 LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
101 return false;
102 }
103 if (track && track->kind() != MediaStreamTrackInterface::kAudioKind) {
deadbeef70ab1a12015-09-28 16:53:55 -0700104 LOG(LS_ERROR) << "SetTrack called on audio RtpSender with " << track->kind()
105 << " track.";
106 return false;
107 }
108 AudioTrackInterface* audio_track = static_cast<AudioTrackInterface*>(track);
109
110 // Detach from old track.
deadbeeffac06552015-11-25 11:26:01 -0800111 if (track_) {
112 track_->RemoveSink(sink_adapter_.get());
113 track_->UnregisterObserver(this);
114 }
115
116 if (can_send_track() && stats_) {
117 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
118 }
deadbeef70ab1a12015-09-28 16:53:55 -0700119
120 // Attach to new track.
deadbeeffac06552015-11-25 11:26:01 -0800121 bool prev_can_send_track = can_send_track();
deadbeef70ab1a12015-09-28 16:53:55 -0700122 track_ = audio_track;
deadbeeffac06552015-11-25 11:26:01 -0800123 if (track_) {
124 cached_track_enabled_ = track_->enabled();
125 track_->RegisterObserver(this);
126 track_->AddSink(sink_adapter_.get());
127 }
128
129 // Update audio provider.
130 if (can_send_track()) {
131 SetAudioSend();
132 if (stats_) {
133 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
134 }
135 } else if (prev_can_send_track) {
136 cricket::AudioOptions options;
137 provider_->SetAudioSend(ssrc_, false, options, nullptr);
138 }
deadbeef70ab1a12015-09-28 16:53:55 -0700139 return true;
140}
141
deadbeeffac06552015-11-25 11:26:01 -0800142void AudioRtpSender::SetSsrc(uint32_t ssrc) {
143 if (stopped_ || ssrc == ssrc_) {
144 return;
145 }
146 // If we are already sending with a particular SSRC, stop sending.
147 if (can_send_track()) {
148 cricket::AudioOptions options;
149 provider_->SetAudioSend(ssrc_, false, options, nullptr);
150 if (stats_) {
151 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
152 }
153 }
154 ssrc_ = ssrc;
155 if (can_send_track()) {
156 SetAudioSend();
157 if (stats_) {
158 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
159 }
160 }
161}
162
deadbeef70ab1a12015-09-28 16:53:55 -0700163void AudioRtpSender::Stop() {
164 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800165 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700166 return;
167 }
deadbeeffac06552015-11-25 11:26:01 -0800168 if (track_) {
169 track_->RemoveSink(sink_adapter_.get());
170 track_->UnregisterObserver(this);
171 }
172 if (can_send_track()) {
173 cricket::AudioOptions options;
174 provider_->SetAudioSend(ssrc_, false, options, nullptr);
175 if (stats_) {
176 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
177 }
178 }
179 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700180}
181
deadbeeffac06552015-11-25 11:26:01 -0800182void AudioRtpSender::SetAudioSend() {
183 RTC_DCHECK(!stopped_ && can_send_track());
deadbeef70ab1a12015-09-28 16:53:55 -0700184 cricket::AudioOptions options;
Tommi3c169782016-01-21 16:12:17 +0100185#if !defined(WEBRTC_CHROMIUM_BUILD)
186 // TODO(tommi): Remove this hack when we move CreateAudioSource out of
187 // PeerConnection. This is a bit of a strange way to apply local audio
188 // options since it is also applied to all streams/channels, local or remote.
tommi6eca7e32015-12-15 04:27:11 -0800189 if (track_->enabled() && track_->GetSource() &&
190 !track_->GetSource()->remote()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700191 // TODO(xians): Remove this static_cast since we should be able to connect
deadbeeffac06552015-11-25 11:26:01 -0800192 // a remote audio track to a peer connection.
deadbeef70ab1a12015-09-28 16:53:55 -0700193 options = static_cast<LocalAudioSource*>(track_->GetSource())->options();
194 }
Tommi3c169782016-01-21 16:12:17 +0100195#endif
deadbeef70ab1a12015-09-28 16:53:55 -0700196
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800197 cricket::AudioSource* source = sink_adapter_.get();
198 ASSERT(source != nullptr);
199 provider_->SetAudioSend(ssrc_, track_->enabled(), options, source);
deadbeef70ab1a12015-09-28 16:53:55 -0700200}
201
202VideoRtpSender::VideoRtpSender(VideoTrackInterface* track,
deadbeeffac06552015-11-25 11:26:01 -0800203 const std::string& stream_id,
deadbeef70ab1a12015-09-28 16:53:55 -0700204 VideoProviderInterface* provider)
205 : id_(track->id()),
deadbeeffac06552015-11-25 11:26:01 -0800206 stream_id_(stream_id),
deadbeef5def7b92015-11-20 11:43:22 -0800207 provider_(provider),
deadbeeffac06552015-11-25 11:26:01 -0800208 track_(track),
deadbeef70ab1a12015-09-28 16:53:55 -0700209 cached_track_enabled_(track->enabled()) {
deadbeeffac06552015-11-25 11:26:01 -0800210 RTC_DCHECK(provider != nullptr);
deadbeef70ab1a12015-09-28 16:53:55 -0700211 track_->RegisterObserver(this);
deadbeef70ab1a12015-09-28 16:53:55 -0700212}
213
deadbeefe1f9d832016-01-14 15:35:42 -0800214VideoRtpSender::VideoRtpSender(VideoTrackInterface* track,
215 VideoProviderInterface* provider)
216 : id_(track->id()),
217 stream_id_(rtc::CreateRandomUuid()),
218 provider_(provider),
219 track_(track),
220 cached_track_enabled_(track->enabled()) {
221 RTC_DCHECK(provider != nullptr);
222 track_->RegisterObserver(this);
223}
224
deadbeeffac06552015-11-25 11:26:01 -0800225VideoRtpSender::VideoRtpSender(VideoProviderInterface* provider)
226 : id_(rtc::CreateRandomUuid()),
227 stream_id_(rtc::CreateRandomUuid()),
228 provider_(provider) {}
229
deadbeef70ab1a12015-09-28 16:53:55 -0700230VideoRtpSender::~VideoRtpSender() {
deadbeef70ab1a12015-09-28 16:53:55 -0700231 Stop();
232}
233
234void VideoRtpSender::OnChanged() {
deadbeeffac06552015-11-25 11:26:01 -0800235 RTC_DCHECK(!stopped_);
deadbeef70ab1a12015-09-28 16:53:55 -0700236 if (cached_track_enabled_ != track_->enabled()) {
237 cached_track_enabled_ = track_->enabled();
deadbeeffac06552015-11-25 11:26:01 -0800238 if (can_send_track()) {
239 SetVideoSend();
240 }
deadbeef70ab1a12015-09-28 16:53:55 -0700241 }
242}
243
244bool VideoRtpSender::SetTrack(MediaStreamTrackInterface* track) {
deadbeeffac06552015-11-25 11:26:01 -0800245 if (stopped_) {
246 LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
247 return false;
248 }
249 if (track && track->kind() != MediaStreamTrackInterface::kVideoKind) {
deadbeef70ab1a12015-09-28 16:53:55 -0700250 LOG(LS_ERROR) << "SetTrack called on video RtpSender with " << track->kind()
251 << " track.";
252 return false;
253 }
254 VideoTrackInterface* video_track = static_cast<VideoTrackInterface*>(track);
255
256 // Detach from old track.
deadbeeffac06552015-11-25 11:26:01 -0800257 if (track_) {
258 track_->UnregisterObserver(this);
259 }
deadbeef70ab1a12015-09-28 16:53:55 -0700260
261 // Attach to new track.
deadbeeffac06552015-11-25 11:26:01 -0800262 bool prev_can_send_track = can_send_track();
deadbeef70ab1a12015-09-28 16:53:55 -0700263 track_ = video_track;
deadbeeffac06552015-11-25 11:26:01 -0800264 if (track_) {
265 cached_track_enabled_ = track_->enabled();
266 track_->RegisterObserver(this);
267 }
268
269 // Update video provider.
270 if (can_send_track()) {
perkja3ede6c2016-03-08 01:27:48 +0100271 VideoTrackSourceInterface* source = track_->GetSource();
deadbeeffac06552015-11-25 11:26:01 -0800272 // TODO(deadbeef): If SetTrack is called with a disabled track, and the
273 // previous track was enabled, this could cause a frame from the new track
274 // to slip out. Really, what we need is for SetCaptureDevice and
275 // SetVideoSend
276 // to be combined into one atomic operation, all the way down to
277 // WebRtcVideoSendStream.
278 provider_->SetCaptureDevice(ssrc_,
279 source ? source->GetVideoCapturer() : nullptr);
280 SetVideoSend();
281 } else if (prev_can_send_track) {
282 provider_->SetCaptureDevice(ssrc_, nullptr);
283 provider_->SetVideoSend(ssrc_, false, nullptr);
284 }
deadbeef70ab1a12015-09-28 16:53:55 -0700285 return true;
286}
287
deadbeeffac06552015-11-25 11:26:01 -0800288void VideoRtpSender::SetSsrc(uint32_t ssrc) {
289 if (stopped_ || ssrc == ssrc_) {
290 return;
291 }
292 // If we are already sending with a particular SSRC, stop sending.
293 if (can_send_track()) {
294 provider_->SetCaptureDevice(ssrc_, nullptr);
295 provider_->SetVideoSend(ssrc_, false, nullptr);
296 }
297 ssrc_ = ssrc;
298 if (can_send_track()) {
perkja3ede6c2016-03-08 01:27:48 +0100299 VideoTrackSourceInterface* source = track_->GetSource();
deadbeeffac06552015-11-25 11:26:01 -0800300 provider_->SetCaptureDevice(ssrc_,
301 source ? source->GetVideoCapturer() : nullptr);
302 SetVideoSend();
303 }
304}
305
deadbeef70ab1a12015-09-28 16:53:55 -0700306void VideoRtpSender::Stop() {
307 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800308 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700309 return;
310 }
deadbeeffac06552015-11-25 11:26:01 -0800311 if (track_) {
312 track_->UnregisterObserver(this);
313 }
314 if (can_send_track()) {
315 provider_->SetCaptureDevice(ssrc_, nullptr);
316 provider_->SetVideoSend(ssrc_, false, nullptr);
317 }
318 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700319}
320
deadbeeffac06552015-11-25 11:26:01 -0800321void VideoRtpSender::SetVideoSend() {
322 RTC_DCHECK(!stopped_ && can_send_track());
perkj0d3eef22016-03-09 02:39:17 +0100323 cricket::VideoOptions options;
perkja3ede6c2016-03-08 01:27:48 +0100324 VideoTrackSourceInterface* source = track_->GetSource();
perkj0d3eef22016-03-09 02:39:17 +0100325 if (source) {
326 options.is_screencast = rtc::Optional<bool>(source->is_screencast());
327 options.video_noise_reduction =
328 rtc::Optional<bool>(source->needs_denoising());
deadbeef70ab1a12015-09-28 16:53:55 -0700329 }
perkj0d3eef22016-03-09 02:39:17 +0100330 provider_->SetVideoSend(ssrc_, track_->enabled(), &options);
deadbeef70ab1a12015-09-28 16:53:55 -0700331}
332
333} // namespace webrtc