blob: cad86f2f77cfa8da4392e578c7c1abf607d95dfd [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "pc/rtpsender.h"
deadbeef6979b022015-09-24 16:47:53 -070012
Steve Anton36b29d12017-10-30 09:57:42 -070013#include <vector>
14
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "api/mediastreaminterface.h"
16#include "pc/localaudiosource.h"
17#include "rtc_base/checks.h"
18#include "rtc_base/helpers.h"
19#include "rtc_base/trace_event.h"
deadbeef70ab1a12015-09-28 16:53:55 -070020
21namespace webrtc {
22
Harald Alvestrandc72af932018-01-11 17:18:19 +010023namespace {
24
25// This function is only expected to be called on the signalling thread.
26int GenerateUniqueId() {
27 static int g_unique_id = 0;
28
29 return ++g_unique_id;
30}
31
32} // namespace
33
deadbeef70ab1a12015-09-28 16:53:55 -070034LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(nullptr) {}
35
36LocalAudioSinkAdapter::~LocalAudioSinkAdapter() {
37 rtc::CritScope lock(&lock_);
38 if (sink_)
39 sink_->OnClose();
40}
41
42void LocalAudioSinkAdapter::OnData(const void* audio_data,
43 int bits_per_sample,
44 int sample_rate,
Peter Kasting69558702016-01-12 16:26:35 -080045 size_t number_of_channels,
deadbeef70ab1a12015-09-28 16:53:55 -070046 size_t number_of_frames) {
47 rtc::CritScope lock(&lock_);
48 if (sink_) {
49 sink_->OnData(audio_data, bits_per_sample, sample_rate, number_of_channels,
50 number_of_frames);
51 }
52}
53
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -080054void LocalAudioSinkAdapter::SetSink(cricket::AudioSource::Sink* sink) {
deadbeef70ab1a12015-09-28 16:53:55 -070055 rtc::CritScope lock(&lock_);
nisseede5da42017-01-12 05:15:36 -080056 RTC_DCHECK(!sink || !sink_);
deadbeef70ab1a12015-09-28 16:53:55 -070057 sink_ = sink;
58}
59
Steve Anton02ee47c2018-01-10 16:26:06 -080060AudioRtpSender::AudioRtpSender(StatsCollector* stats)
61 : AudioRtpSender(nullptr, {rtc::CreateRandomUuid()}, stats) {}
deadbeef70ab1a12015-09-28 16:53:55 -070062
Steve Antonf9381f02017-12-14 10:23:57 -080063AudioRtpSender::AudioRtpSender(rtc::scoped_refptr<AudioTrackInterface> track,
Steve Anton02ee47c2018-01-10 16:26:06 -080064 const std::vector<std::string>& stream_labels,
deadbeefe1f9d832016-01-14 15:35:42 -080065 StatsCollector* stats)
Steve Anton02ee47c2018-01-10 16:26:06 -080066 : id_(track ? track->id() : rtc::CreateRandomUuid()),
67 stream_ids_(stream_labels),
deadbeefe1f9d832016-01-14 15:35:42 -080068 stats_(stats),
69 track_(track),
Steve Anton02ee47c2018-01-10 16:26:06 -080070 dtmf_sender_proxy_(DtmfSenderProxy::Create(
71 rtc::Thread::Current(),
72 DtmfSender::Create(track_, rtc::Thread::Current(), this))),
73 cached_track_enabled_(track ? track->enabled() : false),
Harald Alvestrandc72af932018-01-11 17:18:19 +010074 sink_adapter_(new LocalAudioSinkAdapter()),
75 attachment_id_(track ? GenerateUniqueId() : 0) {
Steve Anton02ee47c2018-01-10 16:26:06 -080076 // TODO(bugs.webrtc.org/7932): Remove once zero or multiple streams are
77 // supported.
78 RTC_DCHECK_EQ(stream_labels.size(), 1u);
79 if (track_) {
80 track_->RegisterObserver(this);
81 track_->AddSink(sink_adapter_.get());
82 }
deadbeef20cb0c12017-02-01 20:27:00 -080083}
deadbeeffac06552015-11-25 11:26:01 -080084
deadbeef70ab1a12015-09-28 16:53:55 -070085AudioRtpSender::~AudioRtpSender() {
deadbeef20cb0c12017-02-01 20:27:00 -080086 // For DtmfSender.
87 SignalDestroyed();
deadbeef70ab1a12015-09-28 16:53:55 -070088 Stop();
89}
90
deadbeef20cb0c12017-02-01 20:27:00 -080091bool AudioRtpSender::CanInsertDtmf() {
92 if (!channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010093 RTC_LOG(LS_ERROR) << "CanInsertDtmf: No audio channel exists.";
deadbeef20cb0c12017-02-01 20:27:00 -080094 return false;
95 }
96 // Check that this RTP sender is active (description has been applied that
97 // matches an SSRC to its ID).
98 if (!ssrc_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010099 RTC_LOG(LS_ERROR) << "CanInsertDtmf: Sender does not have SSRC.";
deadbeef20cb0c12017-02-01 20:27:00 -0800100 return false;
101 }
102 return channel_->CanInsertDtmf();
103}
104
105bool AudioRtpSender::InsertDtmf(int code, int duration) {
106 if (!channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100107 RTC_LOG(LS_ERROR) << "CanInsertDtmf: No audio channel exists.";
deadbeef20cb0c12017-02-01 20:27:00 -0800108 return false;
109 }
110 if (!ssrc_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100111 RTC_LOG(LS_ERROR) << "CanInsertDtmf: Sender does not have SSRC.";
deadbeef20cb0c12017-02-01 20:27:00 -0800112 return false;
113 }
114 if (!channel_->InsertDtmf(ssrc_, code, duration)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100115 RTC_LOG(LS_ERROR) << "Failed to insert DTMF to channel.";
deadbeef20cb0c12017-02-01 20:27:00 -0800116 return false;
117 }
118 return true;
119}
120
121sigslot::signal0<>* AudioRtpSender::GetOnDestroyedSignal() {
122 return &SignalDestroyed;
123}
124
deadbeef70ab1a12015-09-28 16:53:55 -0700125void AudioRtpSender::OnChanged() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200126 TRACE_EVENT0("webrtc", "AudioRtpSender::OnChanged");
deadbeeffac06552015-11-25 11:26:01 -0800127 RTC_DCHECK(!stopped_);
deadbeef70ab1a12015-09-28 16:53:55 -0700128 if (cached_track_enabled_ != track_->enabled()) {
129 cached_track_enabled_ = track_->enabled();
deadbeeffac06552015-11-25 11:26:01 -0800130 if (can_send_track()) {
131 SetAudioSend();
132 }
deadbeef70ab1a12015-09-28 16:53:55 -0700133 }
134}
135
136bool AudioRtpSender::SetTrack(MediaStreamTrackInterface* track) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200137 TRACE_EVENT0("webrtc", "AudioRtpSender::SetTrack");
deadbeeffac06552015-11-25 11:26:01 -0800138 if (stopped_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100139 RTC_LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
deadbeeffac06552015-11-25 11:26:01 -0800140 return false;
141 }
142 if (track && track->kind() != MediaStreamTrackInterface::kAudioKind) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100143 RTC_LOG(LS_ERROR) << "SetTrack called on audio RtpSender with "
144 << track->kind() << " track.";
deadbeef70ab1a12015-09-28 16:53:55 -0700145 return false;
146 }
147 AudioTrackInterface* audio_track = static_cast<AudioTrackInterface*>(track);
148
149 // Detach from old track.
deadbeeffac06552015-11-25 11:26:01 -0800150 if (track_) {
151 track_->RemoveSink(sink_adapter_.get());
152 track_->UnregisterObserver(this);
153 }
154
155 if (can_send_track() && stats_) {
156 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
157 }
deadbeef70ab1a12015-09-28 16:53:55 -0700158
159 // Attach to new track.
deadbeeffac06552015-11-25 11:26:01 -0800160 bool prev_can_send_track = can_send_track();
deadbeef5dd42fd2016-05-02 16:20:01 -0700161 // Keep a reference to the old track to keep it alive until we call
162 // SetAudioSend.
163 rtc::scoped_refptr<AudioTrackInterface> old_track = track_;
deadbeef70ab1a12015-09-28 16:53:55 -0700164 track_ = audio_track;
deadbeeffac06552015-11-25 11:26:01 -0800165 if (track_) {
166 cached_track_enabled_ = track_->enabled();
167 track_->RegisterObserver(this);
168 track_->AddSink(sink_adapter_.get());
169 }
170
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700171 // Update audio channel.
deadbeeffac06552015-11-25 11:26:01 -0800172 if (can_send_track()) {
173 SetAudioSend();
174 if (stats_) {
175 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
176 }
177 } else if (prev_can_send_track) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700178 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800179 }
Harald Alvestrandc72af932018-01-11 17:18:19 +0100180 attachment_id_ = GenerateUniqueId();
deadbeef70ab1a12015-09-28 16:53:55 -0700181 return true;
182}
183
deadbeefa601f5c2016-06-06 14:27:39 -0700184RtpParameters AudioRtpSender::GetParameters() const {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700185 if (!channel_ || stopped_) {
186 return RtpParameters();
187 }
188 return channel_->GetRtpSendParameters(ssrc_);
deadbeefa601f5c2016-06-06 14:27:39 -0700189}
190
191bool AudioRtpSender::SetParameters(const RtpParameters& parameters) {
192 TRACE_EVENT0("webrtc", "AudioRtpSender::SetParameters");
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700193 if (!channel_ || stopped_) {
194 return false;
195 }
196 return channel_->SetRtpSendParameters(ssrc_, parameters);
deadbeefa601f5c2016-06-06 14:27:39 -0700197}
198
deadbeef20cb0c12017-02-01 20:27:00 -0800199rtc::scoped_refptr<DtmfSenderInterface> AudioRtpSender::GetDtmfSender() const {
200 return dtmf_sender_proxy_;
201}
202
deadbeeffac06552015-11-25 11:26:01 -0800203void AudioRtpSender::SetSsrc(uint32_t ssrc) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200204 TRACE_EVENT0("webrtc", "AudioRtpSender::SetSsrc");
deadbeeffac06552015-11-25 11:26:01 -0800205 if (stopped_ || ssrc == ssrc_) {
206 return;
207 }
208 // If we are already sending with a particular SSRC, stop sending.
209 if (can_send_track()) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700210 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800211 if (stats_) {
212 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
213 }
214 }
215 ssrc_ = ssrc;
216 if (can_send_track()) {
217 SetAudioSend();
218 if (stats_) {
219 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
220 }
221 }
222}
223
deadbeef70ab1a12015-09-28 16:53:55 -0700224void AudioRtpSender::Stop() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200225 TRACE_EVENT0("webrtc", "AudioRtpSender::Stop");
deadbeef70ab1a12015-09-28 16:53:55 -0700226 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800227 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700228 return;
229 }
deadbeeffac06552015-11-25 11:26:01 -0800230 if (track_) {
231 track_->RemoveSink(sink_adapter_.get());
232 track_->UnregisterObserver(this);
233 }
234 if (can_send_track()) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700235 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800236 if (stats_) {
237 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
238 }
239 }
240 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700241}
242
deadbeeffac06552015-11-25 11:26:01 -0800243void AudioRtpSender::SetAudioSend() {
kwibergee89e782017-08-09 17:22:01 -0700244 RTC_DCHECK(!stopped_);
245 RTC_DCHECK(can_send_track());
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700246 if (!channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100247 RTC_LOG(LS_ERROR) << "SetAudioSend: No audio channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700248 return;
249 }
deadbeef70ab1a12015-09-28 16:53:55 -0700250 cricket::AudioOptions options;
agouaillardb11fb252017-02-03 06:37:05 -0800251#if !defined(WEBRTC_CHROMIUM_BUILD) && !defined(WEBRTC_WEBKIT_BUILD)
Tommi3c169782016-01-21 16:12:17 +0100252 // TODO(tommi): Remove this hack when we move CreateAudioSource out of
253 // PeerConnection. This is a bit of a strange way to apply local audio
254 // options since it is also applied to all streams/channels, local or remote.
tommi6eca7e32015-12-15 04:27:11 -0800255 if (track_->enabled() && track_->GetSource() &&
256 !track_->GetSource()->remote()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700257 // TODO(xians): Remove this static_cast since we should be able to connect
deadbeeffac06552015-11-25 11:26:01 -0800258 // a remote audio track to a peer connection.
deadbeef70ab1a12015-09-28 16:53:55 -0700259 options = static_cast<LocalAudioSource*>(track_->GetSource())->options();
260 }
Tommi3c169782016-01-21 16:12:17 +0100261#endif
deadbeef70ab1a12015-09-28 16:53:55 -0700262
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800263 cricket::AudioSource* source = sink_adapter_.get();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700264 RTC_DCHECK(source != nullptr);
265 if (!channel_->SetAudioSend(ssrc_, track_->enabled(), &options, source)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100266 RTC_LOG(LS_ERROR) << "SetAudioSend: ssrc is incorrect: " << ssrc_;
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700267 }
268}
269
270void AudioRtpSender::ClearAudioSend() {
271 RTC_DCHECK(ssrc_ != 0);
272 RTC_DCHECK(!stopped_);
273 if (!channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100274 RTC_LOG(LS_WARNING) << "ClearAudioSend: No audio channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700275 return;
276 }
277 cricket::AudioOptions options;
278 if (!channel_->SetAudioSend(ssrc_, false, &options, nullptr)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100279 RTC_LOG(LS_WARNING) << "ClearAudioSend: ssrc is incorrect: " << ssrc_;
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700280 }
deadbeef70ab1a12015-09-28 16:53:55 -0700281}
282
Steve Anton02ee47c2018-01-10 16:26:06 -0800283VideoRtpSender::VideoRtpSender()
284 : VideoRtpSender(nullptr, {rtc::CreateRandomUuid()}) {}
285
286VideoRtpSender::VideoRtpSender(rtc::scoped_refptr<VideoTrackInterface> track,
287 const std::vector<std::string>& stream_labels)
288 : id_(track ? track->id() : rtc::CreateRandomUuid()),
289 stream_ids_(stream_labels),
290 track_(track),
291 cached_track_enabled_(track ? track->enabled() : false),
Harald Alvestrandc72af932018-01-11 17:18:19 +0100292 cached_track_content_hint_(track
293 ? track->content_hint()
294 : VideoTrackInterface::ContentHint::kNone),
295 attachment_id_(track ? GenerateUniqueId() : 0) {
Steve Anton02ee47c2018-01-10 16:26:06 -0800296 // TODO(bugs.webrtc.org/7932): Remove once zero or multiple streams are
297 // supported.
298 RTC_DCHECK_EQ(stream_labels.size(), 1u);
299 if (track_) {
300 track_->RegisterObserver(this);
deadbeef20cb0c12017-02-01 20:27:00 -0800301 }
deadbeef20cb0c12017-02-01 20:27:00 -0800302}
303
deadbeef70ab1a12015-09-28 16:53:55 -0700304VideoRtpSender::~VideoRtpSender() {
deadbeef70ab1a12015-09-28 16:53:55 -0700305 Stop();
306}
307
308void VideoRtpSender::OnChanged() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200309 TRACE_EVENT0("webrtc", "VideoRtpSender::OnChanged");
deadbeeffac06552015-11-25 11:26:01 -0800310 RTC_DCHECK(!stopped_);
pbos5214a0a2016-12-16 15:39:11 -0800311 if (cached_track_enabled_ != track_->enabled() ||
312 cached_track_content_hint_ != track_->content_hint()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700313 cached_track_enabled_ = track_->enabled();
pbos5214a0a2016-12-16 15:39:11 -0800314 cached_track_content_hint_ = track_->content_hint();
deadbeeffac06552015-11-25 11:26:01 -0800315 if (can_send_track()) {
316 SetVideoSend();
317 }
deadbeef70ab1a12015-09-28 16:53:55 -0700318 }
319}
320
321bool VideoRtpSender::SetTrack(MediaStreamTrackInterface* track) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200322 TRACE_EVENT0("webrtc", "VideoRtpSender::SetTrack");
deadbeeffac06552015-11-25 11:26:01 -0800323 if (stopped_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100324 RTC_LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
deadbeeffac06552015-11-25 11:26:01 -0800325 return false;
326 }
327 if (track && track->kind() != MediaStreamTrackInterface::kVideoKind) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100328 RTC_LOG(LS_ERROR) << "SetTrack called on video RtpSender with "
329 << track->kind() << " track.";
deadbeef70ab1a12015-09-28 16:53:55 -0700330 return false;
331 }
332 VideoTrackInterface* video_track = static_cast<VideoTrackInterface*>(track);
333
334 // Detach from old track.
deadbeeffac06552015-11-25 11:26:01 -0800335 if (track_) {
336 track_->UnregisterObserver(this);
337 }
deadbeef70ab1a12015-09-28 16:53:55 -0700338
339 // Attach to new track.
deadbeeffac06552015-11-25 11:26:01 -0800340 bool prev_can_send_track = can_send_track();
deadbeef5dd42fd2016-05-02 16:20:01 -0700341 // Keep a reference to the old track to keep it alive until we call
deadbeef5a4a75a2016-06-02 16:23:38 -0700342 // SetVideoSend.
deadbeef5dd42fd2016-05-02 16:20:01 -0700343 rtc::scoped_refptr<VideoTrackInterface> old_track = track_;
deadbeef70ab1a12015-09-28 16:53:55 -0700344 track_ = video_track;
deadbeeffac06552015-11-25 11:26:01 -0800345 if (track_) {
346 cached_track_enabled_ = track_->enabled();
pbos5214a0a2016-12-16 15:39:11 -0800347 cached_track_content_hint_ = track_->content_hint();
deadbeeffac06552015-11-25 11:26:01 -0800348 track_->RegisterObserver(this);
349 }
350
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700351 // Update video channel.
deadbeeffac06552015-11-25 11:26:01 -0800352 if (can_send_track()) {
deadbeeffac06552015-11-25 11:26:01 -0800353 SetVideoSend();
354 } else if (prev_can_send_track) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700355 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800356 }
Harald Alvestrandc72af932018-01-11 17:18:19 +0100357 attachment_id_ = GenerateUniqueId();
deadbeef70ab1a12015-09-28 16:53:55 -0700358 return true;
359}
360
deadbeefa601f5c2016-06-06 14:27:39 -0700361RtpParameters VideoRtpSender::GetParameters() const {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700362 if (!channel_ || stopped_) {
363 return RtpParameters();
364 }
365 return channel_->GetRtpSendParameters(ssrc_);
deadbeefa601f5c2016-06-06 14:27:39 -0700366}
367
368bool VideoRtpSender::SetParameters(const RtpParameters& parameters) {
369 TRACE_EVENT0("webrtc", "VideoRtpSender::SetParameters");
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700370 if (!channel_ || stopped_) {
371 return false;
372 }
373 return channel_->SetRtpSendParameters(ssrc_, parameters);
deadbeefa601f5c2016-06-06 14:27:39 -0700374}
375
deadbeef20cb0c12017-02-01 20:27:00 -0800376rtc::scoped_refptr<DtmfSenderInterface> VideoRtpSender::GetDtmfSender() const {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100377 RTC_LOG(LS_ERROR) << "Tried to get DTMF sender from video sender.";
deadbeef20cb0c12017-02-01 20:27:00 -0800378 return nullptr;
379}
380
deadbeeffac06552015-11-25 11:26:01 -0800381void VideoRtpSender::SetSsrc(uint32_t ssrc) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200382 TRACE_EVENT0("webrtc", "VideoRtpSender::SetSsrc");
deadbeeffac06552015-11-25 11:26:01 -0800383 if (stopped_ || ssrc == ssrc_) {
384 return;
385 }
386 // If we are already sending with a particular SSRC, stop sending.
387 if (can_send_track()) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700388 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800389 }
390 ssrc_ = ssrc;
391 if (can_send_track()) {
deadbeeffac06552015-11-25 11:26:01 -0800392 SetVideoSend();
393 }
394}
395
deadbeef70ab1a12015-09-28 16:53:55 -0700396void VideoRtpSender::Stop() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200397 TRACE_EVENT0("webrtc", "VideoRtpSender::Stop");
deadbeef70ab1a12015-09-28 16:53:55 -0700398 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800399 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700400 return;
401 }
deadbeeffac06552015-11-25 11:26:01 -0800402 if (track_) {
403 track_->UnregisterObserver(this);
404 }
405 if (can_send_track()) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700406 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800407 }
408 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700409}
410
deadbeeffac06552015-11-25 11:26:01 -0800411void VideoRtpSender::SetVideoSend() {
kwibergee89e782017-08-09 17:22:01 -0700412 RTC_DCHECK(!stopped_);
413 RTC_DCHECK(can_send_track());
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700414 if (!channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100415 RTC_LOG(LS_ERROR) << "SetVideoSend: No video channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700416 return;
417 }
perkj0d3eef22016-03-09 02:39:17 +0100418 cricket::VideoOptions options;
perkja3ede6c2016-03-08 01:27:48 +0100419 VideoTrackSourceInterface* source = track_->GetSource();
perkj0d3eef22016-03-09 02:39:17 +0100420 if (source) {
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100421 options.is_screencast = source->is_screencast();
Perc0d31e92016-03-31 17:23:39 +0200422 options.video_noise_reduction = source->needs_denoising();
deadbeef70ab1a12015-09-28 16:53:55 -0700423 }
pbos5214a0a2016-12-16 15:39:11 -0800424 switch (cached_track_content_hint_) {
425 case VideoTrackInterface::ContentHint::kNone:
426 break;
427 case VideoTrackInterface::ContentHint::kFluid:
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100428 options.is_screencast = false;
pbos5214a0a2016-12-16 15:39:11 -0800429 break;
430 case VideoTrackInterface::ContentHint::kDetailed:
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100431 options.is_screencast = true;
pbos5214a0a2016-12-16 15:39:11 -0800432 break;
433 }
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700434 if (!channel_->SetVideoSend(ssrc_, track_->enabled(), &options, track_)) {
nisseeb4ca4e2017-01-12 02:24:27 -0800435 RTC_NOTREACHED();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700436 }
deadbeef5a4a75a2016-06-02 16:23:38 -0700437}
438
439void VideoRtpSender::ClearVideoSend() {
440 RTC_DCHECK(ssrc_ != 0);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700441 RTC_DCHECK(!stopped_);
442 if (!channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100443 RTC_LOG(LS_WARNING) << "SetVideoSend: No video channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700444 return;
445 }
446 // Allow SetVideoSend to fail since |enable| is false and |source| is null.
447 // This the normal case when the underlying media channel has already been
448 // deleted.
449 channel_->SetVideoSend(ssrc_, false, nullptr, nullptr);
deadbeef70ab1a12015-09-28 16:53:55 -0700450}
451
452} // namespace webrtc