blob: a16a28c193e2bca2825bd1fa9c94ba2933bd035a [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() {
246 RTC_DCHECK(!stopped_ && can_send_track());
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700247 if (!channel_) {
248 LOG(LS_ERROR) << "SetAudioSend: No audio channel exists.";
249 return;
250 }
deadbeef70ab1a12015-09-28 16:53:55 -0700251 cricket::AudioOptions options;
agouaillardb11fb252017-02-03 06:37:05 -0800252#if !defined(WEBRTC_CHROMIUM_BUILD) && !defined(WEBRTC_WEBKIT_BUILD)
Tommi3c169782016-01-21 16:12:17 +0100253 // TODO(tommi): Remove this hack when we move CreateAudioSource out of
254 // PeerConnection. This is a bit of a strange way to apply local audio
255 // options since it is also applied to all streams/channels, local or remote.
tommi6eca7e32015-12-15 04:27:11 -0800256 if (track_->enabled() && track_->GetSource() &&
257 !track_->GetSource()->remote()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700258 // TODO(xians): Remove this static_cast since we should be able to connect
deadbeeffac06552015-11-25 11:26:01 -0800259 // a remote audio track to a peer connection.
deadbeef70ab1a12015-09-28 16:53:55 -0700260 options = static_cast<LocalAudioSource*>(track_->GetSource())->options();
261 }
Tommi3c169782016-01-21 16:12:17 +0100262#endif
deadbeef70ab1a12015-09-28 16:53:55 -0700263
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800264 cricket::AudioSource* source = sink_adapter_.get();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700265 RTC_DCHECK(source != nullptr);
266 if (!channel_->SetAudioSend(ssrc_, track_->enabled(), &options, source)) {
267 LOG(LS_ERROR) << "SetAudioSend: ssrc is incorrect: " << ssrc_;
268 }
269}
270
271void AudioRtpSender::ClearAudioSend() {
272 RTC_DCHECK(ssrc_ != 0);
273 RTC_DCHECK(!stopped_);
274 if (!channel_) {
275 LOG(LS_WARNING) << "ClearAudioSend: No audio channel exists.";
276 return;
277 }
278 cricket::AudioOptions options;
279 if (!channel_->SetAudioSend(ssrc_, false, &options, nullptr)) {
280 LOG(LS_WARNING) << "ClearAudioSend: ssrc is incorrect: " << ssrc_;
281 }
deadbeef70ab1a12015-09-28 16:53:55 -0700282}
283
deadbeef20cb0c12017-02-01 20:27:00 -0800284void AudioRtpSender::CreateDtmfSender() {
285 // Should be on signaling thread.
286 // TODO(deadbeef): Add thread checking to RtpSender/RtpReceiver
287 // implementations.
288 rtc::scoped_refptr<DtmfSenderInterface> sender(
289 DtmfSender::Create(track_, rtc::Thread::Current(), this));
290 if (!sender.get()) {
291 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create.";
292 RTC_NOTREACHED();
293 }
294 dtmf_sender_proxy_ =
295 DtmfSenderProxy::Create(rtc::Thread::Current(), sender.get());
296}
297
deadbeef70ab1a12015-09-28 16:53:55 -0700298VideoRtpSender::VideoRtpSender(VideoTrackInterface* track,
deadbeeffac06552015-11-25 11:26:01 -0800299 const std::string& stream_id,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700300 cricket::VideoChannel* channel)
deadbeef70ab1a12015-09-28 16:53:55 -0700301 : id_(track->id()),
deadbeeffac06552015-11-25 11:26:01 -0800302 stream_id_(stream_id),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700303 channel_(channel),
deadbeeffac06552015-11-25 11:26:01 -0800304 track_(track),
pbos5214a0a2016-12-16 15:39:11 -0800305 cached_track_enabled_(track->enabled()),
306 cached_track_content_hint_(track->content_hint()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700307 track_->RegisterObserver(this);
deadbeef70ab1a12015-09-28 16:53:55 -0700308}
309
deadbeefe1f9d832016-01-14 15:35:42 -0800310VideoRtpSender::VideoRtpSender(VideoTrackInterface* track,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700311 cricket::VideoChannel* channel)
deadbeefe1f9d832016-01-14 15:35:42 -0800312 : id_(track->id()),
313 stream_id_(rtc::CreateRandomUuid()),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700314 channel_(channel),
deadbeefe1f9d832016-01-14 15:35:42 -0800315 track_(track),
pbos5214a0a2016-12-16 15:39:11 -0800316 cached_track_enabled_(track->enabled()),
317 cached_track_content_hint_(track->content_hint()) {
deadbeefe1f9d832016-01-14 15:35:42 -0800318 track_->RegisterObserver(this);
319}
320
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700321VideoRtpSender::VideoRtpSender(cricket::VideoChannel* channel)
deadbeeffac06552015-11-25 11:26:01 -0800322 : id_(rtc::CreateRandomUuid()),
323 stream_id_(rtc::CreateRandomUuid()),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700324 channel_(channel) {}
deadbeeffac06552015-11-25 11:26:01 -0800325
deadbeef70ab1a12015-09-28 16:53:55 -0700326VideoRtpSender::~VideoRtpSender() {
deadbeef70ab1a12015-09-28 16:53:55 -0700327 Stop();
328}
329
330void VideoRtpSender::OnChanged() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200331 TRACE_EVENT0("webrtc", "VideoRtpSender::OnChanged");
deadbeeffac06552015-11-25 11:26:01 -0800332 RTC_DCHECK(!stopped_);
pbos5214a0a2016-12-16 15:39:11 -0800333 if (cached_track_enabled_ != track_->enabled() ||
334 cached_track_content_hint_ != track_->content_hint()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700335 cached_track_enabled_ = track_->enabled();
pbos5214a0a2016-12-16 15:39:11 -0800336 cached_track_content_hint_ = track_->content_hint();
deadbeeffac06552015-11-25 11:26:01 -0800337 if (can_send_track()) {
338 SetVideoSend();
339 }
deadbeef70ab1a12015-09-28 16:53:55 -0700340 }
341}
342
343bool VideoRtpSender::SetTrack(MediaStreamTrackInterface* track) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200344 TRACE_EVENT0("webrtc", "VideoRtpSender::SetTrack");
deadbeeffac06552015-11-25 11:26:01 -0800345 if (stopped_) {
346 LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
347 return false;
348 }
349 if (track && track->kind() != MediaStreamTrackInterface::kVideoKind) {
deadbeef70ab1a12015-09-28 16:53:55 -0700350 LOG(LS_ERROR) << "SetTrack called on video RtpSender with " << track->kind()
351 << " track.";
352 return false;
353 }
354 VideoTrackInterface* video_track = static_cast<VideoTrackInterface*>(track);
355
356 // Detach from old track.
deadbeeffac06552015-11-25 11:26:01 -0800357 if (track_) {
358 track_->UnregisterObserver(this);
359 }
deadbeef70ab1a12015-09-28 16:53:55 -0700360
361 // Attach to new track.
deadbeeffac06552015-11-25 11:26:01 -0800362 bool prev_can_send_track = can_send_track();
deadbeef5dd42fd2016-05-02 16:20:01 -0700363 // Keep a reference to the old track to keep it alive until we call
deadbeef5a4a75a2016-06-02 16:23:38 -0700364 // SetVideoSend.
deadbeef5dd42fd2016-05-02 16:20:01 -0700365 rtc::scoped_refptr<VideoTrackInterface> old_track = track_;
deadbeef70ab1a12015-09-28 16:53:55 -0700366 track_ = video_track;
deadbeeffac06552015-11-25 11:26:01 -0800367 if (track_) {
368 cached_track_enabled_ = track_->enabled();
pbos5214a0a2016-12-16 15:39:11 -0800369 cached_track_content_hint_ = track_->content_hint();
deadbeeffac06552015-11-25 11:26:01 -0800370 track_->RegisterObserver(this);
371 }
372
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700373 // Update video channel.
deadbeeffac06552015-11-25 11:26:01 -0800374 if (can_send_track()) {
deadbeeffac06552015-11-25 11:26:01 -0800375 SetVideoSend();
376 } else if (prev_can_send_track) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700377 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800378 }
deadbeef70ab1a12015-09-28 16:53:55 -0700379 return true;
380}
381
deadbeefa601f5c2016-06-06 14:27:39 -0700382RtpParameters VideoRtpSender::GetParameters() const {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700383 if (!channel_ || stopped_) {
384 return RtpParameters();
385 }
386 return channel_->GetRtpSendParameters(ssrc_);
deadbeefa601f5c2016-06-06 14:27:39 -0700387}
388
389bool VideoRtpSender::SetParameters(const RtpParameters& parameters) {
390 TRACE_EVENT0("webrtc", "VideoRtpSender::SetParameters");
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700391 if (!channel_ || stopped_) {
392 return false;
393 }
394 return channel_->SetRtpSendParameters(ssrc_, parameters);
deadbeefa601f5c2016-06-06 14:27:39 -0700395}
396
deadbeef20cb0c12017-02-01 20:27:00 -0800397rtc::scoped_refptr<DtmfSenderInterface> VideoRtpSender::GetDtmfSender() const {
398 LOG(LS_ERROR) << "Tried to get DTMF sender from video sender.";
399 return nullptr;
400}
401
deadbeeffac06552015-11-25 11:26:01 -0800402void VideoRtpSender::SetSsrc(uint32_t ssrc) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200403 TRACE_EVENT0("webrtc", "VideoRtpSender::SetSsrc");
deadbeeffac06552015-11-25 11:26:01 -0800404 if (stopped_ || ssrc == ssrc_) {
405 return;
406 }
407 // If we are already sending with a particular SSRC, stop sending.
408 if (can_send_track()) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700409 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800410 }
411 ssrc_ = ssrc;
412 if (can_send_track()) {
deadbeeffac06552015-11-25 11:26:01 -0800413 SetVideoSend();
414 }
415}
416
deadbeef70ab1a12015-09-28 16:53:55 -0700417void VideoRtpSender::Stop() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200418 TRACE_EVENT0("webrtc", "VideoRtpSender::Stop");
deadbeef70ab1a12015-09-28 16:53:55 -0700419 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800420 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700421 return;
422 }
deadbeeffac06552015-11-25 11:26:01 -0800423 if (track_) {
424 track_->UnregisterObserver(this);
425 }
426 if (can_send_track()) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700427 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800428 }
429 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700430}
431
deadbeeffac06552015-11-25 11:26:01 -0800432void VideoRtpSender::SetVideoSend() {
433 RTC_DCHECK(!stopped_ && can_send_track());
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700434 if (!channel_) {
435 LOG(LS_ERROR) << "SetVideoSend: No video channel exists.";
436 return;
437 }
perkj0d3eef22016-03-09 02:39:17 +0100438 cricket::VideoOptions options;
perkja3ede6c2016-03-08 01:27:48 +0100439 VideoTrackSourceInterface* source = track_->GetSource();
perkj0d3eef22016-03-09 02:39:17 +0100440 if (source) {
441 options.is_screencast = rtc::Optional<bool>(source->is_screencast());
Perc0d31e92016-03-31 17:23:39 +0200442 options.video_noise_reduction = source->needs_denoising();
deadbeef70ab1a12015-09-28 16:53:55 -0700443 }
pbos5214a0a2016-12-16 15:39:11 -0800444 switch (cached_track_content_hint_) {
445 case VideoTrackInterface::ContentHint::kNone:
446 break;
447 case VideoTrackInterface::ContentHint::kFluid:
448 options.is_screencast = rtc::Optional<bool>(false);
449 break;
450 case VideoTrackInterface::ContentHint::kDetailed:
451 options.is_screencast = rtc::Optional<bool>(true);
452 break;
453 }
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700454 if (!channel_->SetVideoSend(ssrc_, track_->enabled(), &options, track_)) {
nisseeb4ca4e2017-01-12 02:24:27 -0800455 RTC_NOTREACHED();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700456 }
deadbeef5a4a75a2016-06-02 16:23:38 -0700457}
458
459void VideoRtpSender::ClearVideoSend() {
460 RTC_DCHECK(ssrc_ != 0);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700461 RTC_DCHECK(!stopped_);
462 if (!channel_) {
463 LOG(LS_WARNING) << "SetVideoSend: No video channel exists.";
464 return;
465 }
466 // Allow SetVideoSend to fail since |enable| is false and |source| is null.
467 // This the normal case when the underlying media channel has already been
468 // deleted.
469 channel_->SetVideoSend(ssrc_, false, nullptr, nullptr);
deadbeef70ab1a12015-09-28 16:53:55 -0700470}
471
472} // namespace webrtc