blob: 9d920e6f080a029c404c671a2451af6db1f438a2 [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
ossu7bb87ee2017-01-23 04:56:25 -080011#include "webrtc/pc/rtpsender.h"
deadbeef6979b022015-09-24 16:47:53 -070012
perkj9e083d22016-03-20 09:38:40 -070013#include "webrtc/api/mediastreaminterface.h"
ossu7bb87ee2017-01-23 04:56:25 -080014#include "webrtc/pc/localaudiosource.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020015#include "webrtc/rtc_base/checks.h"
16#include "webrtc/rtc_base/helpers.h"
17#include "webrtc/rtc_base/trace_event.h"
deadbeef70ab1a12015-09-28 16:53:55 -070018
19namespace webrtc {
20
21LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(nullptr) {}
22
23LocalAudioSinkAdapter::~LocalAudioSinkAdapter() {
24 rtc::CritScope lock(&lock_);
25 if (sink_)
26 sink_->OnClose();
27}
28
29void LocalAudioSinkAdapter::OnData(const void* audio_data,
30 int bits_per_sample,
31 int sample_rate,
Peter Kasting69558702016-01-12 16:26:35 -080032 size_t number_of_channels,
deadbeef70ab1a12015-09-28 16:53:55 -070033 size_t number_of_frames) {
34 rtc::CritScope lock(&lock_);
35 if (sink_) {
36 sink_->OnData(audio_data, bits_per_sample, sample_rate, number_of_channels,
37 number_of_frames);
38 }
39}
40
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -080041void LocalAudioSinkAdapter::SetSink(cricket::AudioSource::Sink* sink) {
deadbeef70ab1a12015-09-28 16:53:55 -070042 rtc::CritScope lock(&lock_);
nisseede5da42017-01-12 05:15:36 -080043 RTC_DCHECK(!sink || !sink_);
deadbeef70ab1a12015-09-28 16:53:55 -070044 sink_ = sink;
45}
46
47AudioRtpSender::AudioRtpSender(AudioTrackInterface* track,
deadbeeffac06552015-11-25 11:26:01 -080048 const std::string& stream_id,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070049 cricket::VoiceChannel* channel,
deadbeeffac06552015-11-25 11:26:01 -080050 StatsCollector* stats)
deadbeef70ab1a12015-09-28 16:53:55 -070051 : id_(track->id()),
deadbeeffac06552015-11-25 11:26:01 -080052 stream_id_(stream_id),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070053 channel_(channel),
deadbeeffac06552015-11-25 11:26:01 -080054 stats_(stats),
55 track_(track),
deadbeef70ab1a12015-09-28 16:53:55 -070056 cached_track_enabled_(track->enabled()),
57 sink_adapter_(new LocalAudioSinkAdapter()) {
58 track_->RegisterObserver(this);
59 track_->AddSink(sink_adapter_.get());
deadbeef20cb0c12017-02-01 20:27:00 -080060 CreateDtmfSender();
deadbeef70ab1a12015-09-28 16:53:55 -070061}
62
deadbeefe1f9d832016-01-14 15:35:42 -080063AudioRtpSender::AudioRtpSender(AudioTrackInterface* track,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070064 cricket::VoiceChannel* channel,
deadbeefe1f9d832016-01-14 15:35:42 -080065 StatsCollector* stats)
66 : id_(track->id()),
67 stream_id_(rtc::CreateRandomUuid()),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070068 channel_(channel),
deadbeefe1f9d832016-01-14 15:35:42 -080069 stats_(stats),
70 track_(track),
71 cached_track_enabled_(track->enabled()),
72 sink_adapter_(new LocalAudioSinkAdapter()) {
deadbeefe1f9d832016-01-14 15:35:42 -080073 track_->RegisterObserver(this);
74 track_->AddSink(sink_adapter_.get());
deadbeef20cb0c12017-02-01 20:27:00 -080075 CreateDtmfSender();
deadbeefe1f9d832016-01-14 15:35:42 -080076}
77
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070078AudioRtpSender::AudioRtpSender(cricket::VoiceChannel* channel,
deadbeeffac06552015-11-25 11:26:01 -080079 StatsCollector* stats)
80 : id_(rtc::CreateRandomUuid()),
81 stream_id_(rtc::CreateRandomUuid()),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070082 channel_(channel),
deadbeeffac06552015-11-25 11:26:01 -080083 stats_(stats),
deadbeef20cb0c12017-02-01 20:27:00 -080084 sink_adapter_(new LocalAudioSinkAdapter()) {
85 CreateDtmfSender();
86}
deadbeeffac06552015-11-25 11:26:01 -080087
deadbeef70ab1a12015-09-28 16:53:55 -070088AudioRtpSender::~AudioRtpSender() {
deadbeef20cb0c12017-02-01 20:27:00 -080089 // For DtmfSender.
90 SignalDestroyed();
deadbeef70ab1a12015-09-28 16:53:55 -070091 Stop();
92}
93
deadbeef20cb0c12017-02-01 20:27:00 -080094bool AudioRtpSender::CanInsertDtmf() {
95 if (!channel_) {
96 LOG(LS_ERROR) << "CanInsertDtmf: No audio channel exists.";
97 return false;
98 }
99 // Check that this RTP sender is active (description has been applied that
100 // matches an SSRC to its ID).
101 if (!ssrc_) {
102 LOG(LS_ERROR) << "CanInsertDtmf: Sender does not have SSRC.";
103 return false;
104 }
105 return channel_->CanInsertDtmf();
106}
107
108bool AudioRtpSender::InsertDtmf(int code, int duration) {
109 if (!channel_) {
110 LOG(LS_ERROR) << "CanInsertDtmf: No audio channel exists.";
111 return false;
112 }
113 if (!ssrc_) {
114 LOG(LS_ERROR) << "CanInsertDtmf: Sender does not have SSRC.";
115 return false;
116 }
117 if (!channel_->InsertDtmf(ssrc_, code, duration)) {
118 LOG(LS_ERROR) << "Failed to insert DTMF to channel.";
119 return false;
120 }
121 return true;
122}
123
124sigslot::signal0<>* AudioRtpSender::GetOnDestroyedSignal() {
125 return &SignalDestroyed;
126}
127
deadbeef70ab1a12015-09-28 16:53:55 -0700128void AudioRtpSender::OnChanged() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200129 TRACE_EVENT0("webrtc", "AudioRtpSender::OnChanged");
deadbeeffac06552015-11-25 11:26:01 -0800130 RTC_DCHECK(!stopped_);
deadbeef70ab1a12015-09-28 16:53:55 -0700131 if (cached_track_enabled_ != track_->enabled()) {
132 cached_track_enabled_ = track_->enabled();
deadbeeffac06552015-11-25 11:26:01 -0800133 if (can_send_track()) {
134 SetAudioSend();
135 }
deadbeef70ab1a12015-09-28 16:53:55 -0700136 }
137}
138
139bool AudioRtpSender::SetTrack(MediaStreamTrackInterface* track) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200140 TRACE_EVENT0("webrtc", "AudioRtpSender::SetTrack");
deadbeeffac06552015-11-25 11:26:01 -0800141 if (stopped_) {
142 LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
143 return false;
144 }
145 if (track && track->kind() != MediaStreamTrackInterface::kAudioKind) {
deadbeef70ab1a12015-09-28 16:53:55 -0700146 LOG(LS_ERROR) << "SetTrack called on audio RtpSender with " << track->kind()
147 << " track.";
148 return false;
149 }
150 AudioTrackInterface* audio_track = static_cast<AudioTrackInterface*>(track);
151
152 // Detach from old track.
deadbeeffac06552015-11-25 11:26:01 -0800153 if (track_) {
154 track_->RemoveSink(sink_adapter_.get());
155 track_->UnregisterObserver(this);
156 }
157
158 if (can_send_track() && stats_) {
159 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
160 }
deadbeef70ab1a12015-09-28 16:53:55 -0700161
162 // Attach to new track.
deadbeeffac06552015-11-25 11:26:01 -0800163 bool prev_can_send_track = can_send_track();
deadbeef5dd42fd2016-05-02 16:20:01 -0700164 // Keep a reference to the old track to keep it alive until we call
165 // SetAudioSend.
166 rtc::scoped_refptr<AudioTrackInterface> old_track = track_;
deadbeef70ab1a12015-09-28 16:53:55 -0700167 track_ = audio_track;
deadbeeffac06552015-11-25 11:26:01 -0800168 if (track_) {
169 cached_track_enabled_ = track_->enabled();
170 track_->RegisterObserver(this);
171 track_->AddSink(sink_adapter_.get());
172 }
173
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700174 // Update audio channel.
deadbeeffac06552015-11-25 11:26:01 -0800175 if (can_send_track()) {
176 SetAudioSend();
177 if (stats_) {
178 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
179 }
180 } else if (prev_can_send_track) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700181 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800182 }
deadbeef70ab1a12015-09-28 16:53:55 -0700183 return true;
184}
185
deadbeefa601f5c2016-06-06 14:27:39 -0700186RtpParameters AudioRtpSender::GetParameters() const {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700187 if (!channel_ || stopped_) {
188 return RtpParameters();
189 }
190 return channel_->GetRtpSendParameters(ssrc_);
deadbeefa601f5c2016-06-06 14:27:39 -0700191}
192
193bool AudioRtpSender::SetParameters(const RtpParameters& parameters) {
194 TRACE_EVENT0("webrtc", "AudioRtpSender::SetParameters");
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700195 if (!channel_ || stopped_) {
196 return false;
197 }
198 return channel_->SetRtpSendParameters(ssrc_, parameters);
deadbeefa601f5c2016-06-06 14:27:39 -0700199}
200
deadbeef20cb0c12017-02-01 20:27:00 -0800201rtc::scoped_refptr<DtmfSenderInterface> AudioRtpSender::GetDtmfSender() const {
202 return dtmf_sender_proxy_;
203}
204
deadbeeffac06552015-11-25 11:26:01 -0800205void AudioRtpSender::SetSsrc(uint32_t ssrc) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200206 TRACE_EVENT0("webrtc", "AudioRtpSender::SetSsrc");
deadbeeffac06552015-11-25 11:26:01 -0800207 if (stopped_ || ssrc == ssrc_) {
208 return;
209 }
210 // If we are already sending with a particular SSRC, stop sending.
211 if (can_send_track()) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700212 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800213 if (stats_) {
214 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
215 }
216 }
217 ssrc_ = ssrc;
218 if (can_send_track()) {
219 SetAudioSend();
220 if (stats_) {
221 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
222 }
223 }
224}
225
deadbeef70ab1a12015-09-28 16:53:55 -0700226void AudioRtpSender::Stop() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200227 TRACE_EVENT0("webrtc", "AudioRtpSender::Stop");
deadbeef70ab1a12015-09-28 16:53:55 -0700228 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800229 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700230 return;
231 }
deadbeeffac06552015-11-25 11:26:01 -0800232 if (track_) {
233 track_->RemoveSink(sink_adapter_.get());
234 track_->UnregisterObserver(this);
235 }
236 if (can_send_track()) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700237 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800238 if (stats_) {
239 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
240 }
241 }
242 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700243}
244
deadbeeffac06552015-11-25 11:26:01 -0800245void AudioRtpSender::SetAudioSend() {
kwibergee89e782017-08-09 17:22:01 -0700246 RTC_DCHECK(!stopped_);
247 RTC_DCHECK(can_send_track());
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700248 if (!channel_) {
249 LOG(LS_ERROR) << "SetAudioSend: No audio channel exists.";
250 return;
251 }
deadbeef70ab1a12015-09-28 16:53:55 -0700252 cricket::AudioOptions options;
agouaillardb11fb252017-02-03 06:37:05 -0800253#if !defined(WEBRTC_CHROMIUM_BUILD) && !defined(WEBRTC_WEBKIT_BUILD)
Tommi3c169782016-01-21 16:12:17 +0100254 // TODO(tommi): Remove this hack when we move CreateAudioSource out of
255 // PeerConnection. This is a bit of a strange way to apply local audio
256 // options since it is also applied to all streams/channels, local or remote.
tommi6eca7e32015-12-15 04:27:11 -0800257 if (track_->enabled() && track_->GetSource() &&
258 !track_->GetSource()->remote()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700259 // TODO(xians): Remove this static_cast since we should be able to connect
deadbeeffac06552015-11-25 11:26:01 -0800260 // a remote audio track to a peer connection.
deadbeef70ab1a12015-09-28 16:53:55 -0700261 options = static_cast<LocalAudioSource*>(track_->GetSource())->options();
262 }
Tommi3c169782016-01-21 16:12:17 +0100263#endif
deadbeef70ab1a12015-09-28 16:53:55 -0700264
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800265 cricket::AudioSource* source = sink_adapter_.get();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700266 RTC_DCHECK(source != nullptr);
267 if (!channel_->SetAudioSend(ssrc_, track_->enabled(), &options, source)) {
268 LOG(LS_ERROR) << "SetAudioSend: ssrc is incorrect: " << ssrc_;
269 }
270}
271
272void AudioRtpSender::ClearAudioSend() {
273 RTC_DCHECK(ssrc_ != 0);
274 RTC_DCHECK(!stopped_);
275 if (!channel_) {
276 LOG(LS_WARNING) << "ClearAudioSend: No audio channel exists.";
277 return;
278 }
279 cricket::AudioOptions options;
280 if (!channel_->SetAudioSend(ssrc_, false, &options, nullptr)) {
281 LOG(LS_WARNING) << "ClearAudioSend: ssrc is incorrect: " << ssrc_;
282 }
deadbeef70ab1a12015-09-28 16:53:55 -0700283}
284
deadbeef20cb0c12017-02-01 20:27:00 -0800285void AudioRtpSender::CreateDtmfSender() {
286 // Should be on signaling thread.
287 // TODO(deadbeef): Add thread checking to RtpSender/RtpReceiver
288 // implementations.
289 rtc::scoped_refptr<DtmfSenderInterface> sender(
290 DtmfSender::Create(track_, rtc::Thread::Current(), this));
291 if (!sender.get()) {
292 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create.";
293 RTC_NOTREACHED();
294 }
295 dtmf_sender_proxy_ =
296 DtmfSenderProxy::Create(rtc::Thread::Current(), sender.get());
297}
298
deadbeef70ab1a12015-09-28 16:53:55 -0700299VideoRtpSender::VideoRtpSender(VideoTrackInterface* track,
deadbeeffac06552015-11-25 11:26:01 -0800300 const std::string& stream_id,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700301 cricket::VideoChannel* channel)
deadbeef70ab1a12015-09-28 16:53:55 -0700302 : id_(track->id()),
deadbeeffac06552015-11-25 11:26:01 -0800303 stream_id_(stream_id),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700304 channel_(channel),
deadbeeffac06552015-11-25 11:26:01 -0800305 track_(track),
pbos5214a0a2016-12-16 15:39:11 -0800306 cached_track_enabled_(track->enabled()),
307 cached_track_content_hint_(track->content_hint()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700308 track_->RegisterObserver(this);
deadbeef70ab1a12015-09-28 16:53:55 -0700309}
310
deadbeefe1f9d832016-01-14 15:35:42 -0800311VideoRtpSender::VideoRtpSender(VideoTrackInterface* track,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700312 cricket::VideoChannel* channel)
deadbeefe1f9d832016-01-14 15:35:42 -0800313 : id_(track->id()),
314 stream_id_(rtc::CreateRandomUuid()),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700315 channel_(channel),
deadbeefe1f9d832016-01-14 15:35:42 -0800316 track_(track),
pbos5214a0a2016-12-16 15:39:11 -0800317 cached_track_enabled_(track->enabled()),
318 cached_track_content_hint_(track->content_hint()) {
deadbeefe1f9d832016-01-14 15:35:42 -0800319 track_->RegisterObserver(this);
320}
321
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700322VideoRtpSender::VideoRtpSender(cricket::VideoChannel* channel)
deadbeeffac06552015-11-25 11:26:01 -0800323 : id_(rtc::CreateRandomUuid()),
324 stream_id_(rtc::CreateRandomUuid()),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700325 channel_(channel) {}
deadbeeffac06552015-11-25 11:26:01 -0800326
deadbeef70ab1a12015-09-28 16:53:55 -0700327VideoRtpSender::~VideoRtpSender() {
deadbeef70ab1a12015-09-28 16:53:55 -0700328 Stop();
329}
330
331void VideoRtpSender::OnChanged() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200332 TRACE_EVENT0("webrtc", "VideoRtpSender::OnChanged");
deadbeeffac06552015-11-25 11:26:01 -0800333 RTC_DCHECK(!stopped_);
pbos5214a0a2016-12-16 15:39:11 -0800334 if (cached_track_enabled_ != track_->enabled() ||
335 cached_track_content_hint_ != track_->content_hint()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700336 cached_track_enabled_ = track_->enabled();
pbos5214a0a2016-12-16 15:39:11 -0800337 cached_track_content_hint_ = track_->content_hint();
deadbeeffac06552015-11-25 11:26:01 -0800338 if (can_send_track()) {
339 SetVideoSend();
340 }
deadbeef70ab1a12015-09-28 16:53:55 -0700341 }
342}
343
344bool VideoRtpSender::SetTrack(MediaStreamTrackInterface* track) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200345 TRACE_EVENT0("webrtc", "VideoRtpSender::SetTrack");
deadbeeffac06552015-11-25 11:26:01 -0800346 if (stopped_) {
347 LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
348 return false;
349 }
350 if (track && track->kind() != MediaStreamTrackInterface::kVideoKind) {
deadbeef70ab1a12015-09-28 16:53:55 -0700351 LOG(LS_ERROR) << "SetTrack called on video RtpSender with " << track->kind()
352 << " track.";
353 return false;
354 }
355 VideoTrackInterface* video_track = static_cast<VideoTrackInterface*>(track);
356
357 // Detach from old track.
deadbeeffac06552015-11-25 11:26:01 -0800358 if (track_) {
359 track_->UnregisterObserver(this);
360 }
deadbeef70ab1a12015-09-28 16:53:55 -0700361
362 // Attach to new track.
deadbeeffac06552015-11-25 11:26:01 -0800363 bool prev_can_send_track = can_send_track();
deadbeef5dd42fd2016-05-02 16:20:01 -0700364 // Keep a reference to the old track to keep it alive until we call
deadbeef5a4a75a2016-06-02 16:23:38 -0700365 // SetVideoSend.
deadbeef5dd42fd2016-05-02 16:20:01 -0700366 rtc::scoped_refptr<VideoTrackInterface> old_track = track_;
deadbeef70ab1a12015-09-28 16:53:55 -0700367 track_ = video_track;
deadbeeffac06552015-11-25 11:26:01 -0800368 if (track_) {
369 cached_track_enabled_ = track_->enabled();
pbos5214a0a2016-12-16 15:39:11 -0800370 cached_track_content_hint_ = track_->content_hint();
deadbeeffac06552015-11-25 11:26:01 -0800371 track_->RegisterObserver(this);
372 }
373
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700374 // Update video channel.
deadbeeffac06552015-11-25 11:26:01 -0800375 if (can_send_track()) {
deadbeeffac06552015-11-25 11:26:01 -0800376 SetVideoSend();
377 } else if (prev_can_send_track) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700378 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800379 }
deadbeef70ab1a12015-09-28 16:53:55 -0700380 return true;
381}
382
deadbeefa601f5c2016-06-06 14:27:39 -0700383RtpParameters VideoRtpSender::GetParameters() const {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700384 if (!channel_ || stopped_) {
385 return RtpParameters();
386 }
387 return channel_->GetRtpSendParameters(ssrc_);
deadbeefa601f5c2016-06-06 14:27:39 -0700388}
389
390bool VideoRtpSender::SetParameters(const RtpParameters& parameters) {
391 TRACE_EVENT0("webrtc", "VideoRtpSender::SetParameters");
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700392 if (!channel_ || stopped_) {
393 return false;
394 }
395 return channel_->SetRtpSendParameters(ssrc_, parameters);
deadbeefa601f5c2016-06-06 14:27:39 -0700396}
397
deadbeef20cb0c12017-02-01 20:27:00 -0800398rtc::scoped_refptr<DtmfSenderInterface> VideoRtpSender::GetDtmfSender() const {
399 LOG(LS_ERROR) << "Tried to get DTMF sender from video sender.";
400 return nullptr;
401}
402
deadbeeffac06552015-11-25 11:26:01 -0800403void VideoRtpSender::SetSsrc(uint32_t ssrc) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200404 TRACE_EVENT0("webrtc", "VideoRtpSender::SetSsrc");
deadbeeffac06552015-11-25 11:26:01 -0800405 if (stopped_ || ssrc == ssrc_) {
406 return;
407 }
408 // If we are already sending with a particular SSRC, stop sending.
409 if (can_send_track()) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700410 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800411 }
412 ssrc_ = ssrc;
413 if (can_send_track()) {
deadbeeffac06552015-11-25 11:26:01 -0800414 SetVideoSend();
415 }
416}
417
deadbeef70ab1a12015-09-28 16:53:55 -0700418void VideoRtpSender::Stop() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200419 TRACE_EVENT0("webrtc", "VideoRtpSender::Stop");
deadbeef70ab1a12015-09-28 16:53:55 -0700420 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800421 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700422 return;
423 }
deadbeeffac06552015-11-25 11:26:01 -0800424 if (track_) {
425 track_->UnregisterObserver(this);
426 }
427 if (can_send_track()) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700428 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800429 }
430 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700431}
432
deadbeeffac06552015-11-25 11:26:01 -0800433void VideoRtpSender::SetVideoSend() {
kwibergee89e782017-08-09 17:22:01 -0700434 RTC_DCHECK(!stopped_);
435 RTC_DCHECK(can_send_track());
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700436 if (!channel_) {
437 LOG(LS_ERROR) << "SetVideoSend: No video channel exists.";
438 return;
439 }
perkj0d3eef22016-03-09 02:39:17 +0100440 cricket::VideoOptions options;
perkja3ede6c2016-03-08 01:27:48 +0100441 VideoTrackSourceInterface* source = track_->GetSource();
perkj0d3eef22016-03-09 02:39:17 +0100442 if (source) {
443 options.is_screencast = rtc::Optional<bool>(source->is_screencast());
Perc0d31e92016-03-31 17:23:39 +0200444 options.video_noise_reduction = source->needs_denoising();
deadbeef70ab1a12015-09-28 16:53:55 -0700445 }
pbos5214a0a2016-12-16 15:39:11 -0800446 switch (cached_track_content_hint_) {
447 case VideoTrackInterface::ContentHint::kNone:
448 break;
449 case VideoTrackInterface::ContentHint::kFluid:
450 options.is_screencast = rtc::Optional<bool>(false);
451 break;
452 case VideoTrackInterface::ContentHint::kDetailed:
453 options.is_screencast = rtc::Optional<bool>(true);
454 break;
455 }
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700456 if (!channel_->SetVideoSend(ssrc_, track_->enabled(), &options, track_)) {
nisseeb4ca4e2017-01-12 02:24:27 -0800457 RTC_NOTREACHED();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700458 }
deadbeef5a4a75a2016-06-02 16:23:38 -0700459}
460
461void VideoRtpSender::ClearVideoSend() {
462 RTC_DCHECK(ssrc_ != 0);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700463 RTC_DCHECK(!stopped_);
464 if (!channel_) {
465 LOG(LS_WARNING) << "SetVideoSend: No video channel exists.";
466 return;
467 }
468 // Allow SetVideoSend to fail since |enable| is false and |source| is null.
469 // This the normal case when the underlying media channel has already been
470 // deleted.
471 channel_->SetVideoSend(ssrc_, false, nullptr, nullptr);
deadbeef70ab1a12015-09-28 16:53:55 -0700472}
473
474} // namespace webrtc