blob: 3d5594c13ce2b016b72d2aeb9c9d180f3a980b3a [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "api/mediastreaminterface.h"
14#include "pc/localaudiosource.h"
15#include "rtc_base/checks.h"
16#include "rtc_base/helpers.h"
17#include "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,
Steve Anton8ffb9c32017-08-31 15:45:38 -070048 const std::vector<std::string>& stream_ids,
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()),
Steve Anton8ffb9c32017-08-31 15:45:38 -070052 stream_ids_(stream_ids),
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()) {
Steve Anton8ffb9c32017-08-31 15:45:38 -070058 // TODO(steveanton): Relax this constraint once more Unified Plan work is
59 // done.
60 RTC_CHECK(stream_ids_.size() == 1U);
deadbeef70ab1a12015-09-28 16:53:55 -070061 track_->RegisterObserver(this);
62 track_->AddSink(sink_adapter_.get());
deadbeef20cb0c12017-02-01 20:27:00 -080063 CreateDtmfSender();
deadbeef70ab1a12015-09-28 16:53:55 -070064}
65
deadbeefe1f9d832016-01-14 15:35:42 -080066AudioRtpSender::AudioRtpSender(AudioTrackInterface* track,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070067 cricket::VoiceChannel* channel,
deadbeefe1f9d832016-01-14 15:35:42 -080068 StatsCollector* stats)
69 : id_(track->id()),
Steve Anton8ffb9c32017-08-31 15:45:38 -070070 // TODO(steveanton): With Unified Plan this should be empty.
71 stream_ids_({rtc::CreateRandomUuid()}),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070072 channel_(channel),
deadbeefe1f9d832016-01-14 15:35:42 -080073 stats_(stats),
74 track_(track),
75 cached_track_enabled_(track->enabled()),
76 sink_adapter_(new LocalAudioSinkAdapter()) {
deadbeefe1f9d832016-01-14 15:35:42 -080077 track_->RegisterObserver(this);
78 track_->AddSink(sink_adapter_.get());
deadbeef20cb0c12017-02-01 20:27:00 -080079 CreateDtmfSender();
deadbeefe1f9d832016-01-14 15:35:42 -080080}
81
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070082AudioRtpSender::AudioRtpSender(cricket::VoiceChannel* channel,
deadbeeffac06552015-11-25 11:26:01 -080083 StatsCollector* stats)
84 : id_(rtc::CreateRandomUuid()),
Steve Anton8ffb9c32017-08-31 15:45:38 -070085 // TODO(steveanton): With Unified Plan this should be empty.
86 stream_ids_({rtc::CreateRandomUuid()}),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070087 channel_(channel),
deadbeeffac06552015-11-25 11:26:01 -080088 stats_(stats),
deadbeef20cb0c12017-02-01 20:27:00 -080089 sink_adapter_(new LocalAudioSinkAdapter()) {
90 CreateDtmfSender();
91}
deadbeeffac06552015-11-25 11:26:01 -080092
deadbeef70ab1a12015-09-28 16:53:55 -070093AudioRtpSender::~AudioRtpSender() {
deadbeef20cb0c12017-02-01 20:27:00 -080094 // For DtmfSender.
95 SignalDestroyed();
deadbeef70ab1a12015-09-28 16:53:55 -070096 Stop();
97}
98
deadbeef20cb0c12017-02-01 20:27:00 -080099bool AudioRtpSender::CanInsertDtmf() {
100 if (!channel_) {
101 LOG(LS_ERROR) << "CanInsertDtmf: No audio channel exists.";
102 return false;
103 }
104 // Check that this RTP sender is active (description has been applied that
105 // matches an SSRC to its ID).
106 if (!ssrc_) {
107 LOG(LS_ERROR) << "CanInsertDtmf: Sender does not have SSRC.";
108 return false;
109 }
110 return channel_->CanInsertDtmf();
111}
112
113bool AudioRtpSender::InsertDtmf(int code, int duration) {
114 if (!channel_) {
115 LOG(LS_ERROR) << "CanInsertDtmf: No audio channel exists.";
116 return false;
117 }
118 if (!ssrc_) {
119 LOG(LS_ERROR) << "CanInsertDtmf: Sender does not have SSRC.";
120 return false;
121 }
122 if (!channel_->InsertDtmf(ssrc_, code, duration)) {
123 LOG(LS_ERROR) << "Failed to insert DTMF to channel.";
124 return false;
125 }
126 return true;
127}
128
129sigslot::signal0<>* AudioRtpSender::GetOnDestroyedSignal() {
130 return &SignalDestroyed;
131}
132
deadbeef70ab1a12015-09-28 16:53:55 -0700133void AudioRtpSender::OnChanged() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200134 TRACE_EVENT0("webrtc", "AudioRtpSender::OnChanged");
deadbeeffac06552015-11-25 11:26:01 -0800135 RTC_DCHECK(!stopped_);
deadbeef70ab1a12015-09-28 16:53:55 -0700136 if (cached_track_enabled_ != track_->enabled()) {
137 cached_track_enabled_ = track_->enabled();
deadbeeffac06552015-11-25 11:26:01 -0800138 if (can_send_track()) {
139 SetAudioSend();
140 }
deadbeef70ab1a12015-09-28 16:53:55 -0700141 }
142}
143
144bool AudioRtpSender::SetTrack(MediaStreamTrackInterface* track) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200145 TRACE_EVENT0("webrtc", "AudioRtpSender::SetTrack");
deadbeeffac06552015-11-25 11:26:01 -0800146 if (stopped_) {
147 LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
148 return false;
149 }
150 if (track && track->kind() != MediaStreamTrackInterface::kAudioKind) {
deadbeef70ab1a12015-09-28 16:53:55 -0700151 LOG(LS_ERROR) << "SetTrack called on audio RtpSender with " << track->kind()
152 << " track.";
153 return false;
154 }
155 AudioTrackInterface* audio_track = static_cast<AudioTrackInterface*>(track);
156
157 // Detach from old track.
deadbeeffac06552015-11-25 11:26:01 -0800158 if (track_) {
159 track_->RemoveSink(sink_adapter_.get());
160 track_->UnregisterObserver(this);
161 }
162
163 if (can_send_track() && stats_) {
164 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
165 }
deadbeef70ab1a12015-09-28 16:53:55 -0700166
167 // Attach to new track.
deadbeeffac06552015-11-25 11:26:01 -0800168 bool prev_can_send_track = can_send_track();
deadbeef5dd42fd2016-05-02 16:20:01 -0700169 // Keep a reference to the old track to keep it alive until we call
170 // SetAudioSend.
171 rtc::scoped_refptr<AudioTrackInterface> old_track = track_;
deadbeef70ab1a12015-09-28 16:53:55 -0700172 track_ = audio_track;
deadbeeffac06552015-11-25 11:26:01 -0800173 if (track_) {
174 cached_track_enabled_ = track_->enabled();
175 track_->RegisterObserver(this);
176 track_->AddSink(sink_adapter_.get());
177 }
178
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700179 // Update audio channel.
deadbeeffac06552015-11-25 11:26:01 -0800180 if (can_send_track()) {
181 SetAudioSend();
182 if (stats_) {
183 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
184 }
185 } else if (prev_can_send_track) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700186 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800187 }
deadbeef70ab1a12015-09-28 16:53:55 -0700188 return true;
189}
190
deadbeefa601f5c2016-06-06 14:27:39 -0700191RtpParameters AudioRtpSender::GetParameters() const {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700192 if (!channel_ || stopped_) {
193 return RtpParameters();
194 }
195 return channel_->GetRtpSendParameters(ssrc_);
deadbeefa601f5c2016-06-06 14:27:39 -0700196}
197
198bool AudioRtpSender::SetParameters(const RtpParameters& parameters) {
199 TRACE_EVENT0("webrtc", "AudioRtpSender::SetParameters");
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700200 if (!channel_ || stopped_) {
201 return false;
202 }
203 return channel_->SetRtpSendParameters(ssrc_, parameters);
deadbeefa601f5c2016-06-06 14:27:39 -0700204}
205
deadbeef20cb0c12017-02-01 20:27:00 -0800206rtc::scoped_refptr<DtmfSenderInterface> AudioRtpSender::GetDtmfSender() const {
207 return dtmf_sender_proxy_;
208}
209
deadbeeffac06552015-11-25 11:26:01 -0800210void AudioRtpSender::SetSsrc(uint32_t ssrc) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200211 TRACE_EVENT0("webrtc", "AudioRtpSender::SetSsrc");
deadbeeffac06552015-11-25 11:26:01 -0800212 if (stopped_ || ssrc == ssrc_) {
213 return;
214 }
215 // If we are already sending with a particular SSRC, stop sending.
216 if (can_send_track()) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700217 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800218 if (stats_) {
219 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
220 }
221 }
222 ssrc_ = ssrc;
223 if (can_send_track()) {
224 SetAudioSend();
225 if (stats_) {
226 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
227 }
228 }
229}
230
deadbeef70ab1a12015-09-28 16:53:55 -0700231void AudioRtpSender::Stop() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200232 TRACE_EVENT0("webrtc", "AudioRtpSender::Stop");
deadbeef70ab1a12015-09-28 16:53:55 -0700233 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800234 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700235 return;
236 }
deadbeeffac06552015-11-25 11:26:01 -0800237 if (track_) {
238 track_->RemoveSink(sink_adapter_.get());
239 track_->UnregisterObserver(this);
240 }
241 if (can_send_track()) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700242 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800243 if (stats_) {
244 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
245 }
246 }
247 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700248}
249
deadbeeffac06552015-11-25 11:26:01 -0800250void AudioRtpSender::SetAudioSend() {
kwibergee89e782017-08-09 17:22:01 -0700251 RTC_DCHECK(!stopped_);
252 RTC_DCHECK(can_send_track());
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700253 if (!channel_) {
254 LOG(LS_ERROR) << "SetAudioSend: No audio channel exists.";
255 return;
256 }
deadbeef70ab1a12015-09-28 16:53:55 -0700257 cricket::AudioOptions options;
agouaillardb11fb252017-02-03 06:37:05 -0800258#if !defined(WEBRTC_CHROMIUM_BUILD) && !defined(WEBRTC_WEBKIT_BUILD)
Tommi3c169782016-01-21 16:12:17 +0100259 // TODO(tommi): Remove this hack when we move CreateAudioSource out of
260 // PeerConnection. This is a bit of a strange way to apply local audio
261 // options since it is also applied to all streams/channels, local or remote.
tommi6eca7e32015-12-15 04:27:11 -0800262 if (track_->enabled() && track_->GetSource() &&
263 !track_->GetSource()->remote()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700264 // TODO(xians): Remove this static_cast since we should be able to connect
deadbeeffac06552015-11-25 11:26:01 -0800265 // a remote audio track to a peer connection.
deadbeef70ab1a12015-09-28 16:53:55 -0700266 options = static_cast<LocalAudioSource*>(track_->GetSource())->options();
267 }
Tommi3c169782016-01-21 16:12:17 +0100268#endif
deadbeef70ab1a12015-09-28 16:53:55 -0700269
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800270 cricket::AudioSource* source = sink_adapter_.get();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700271 RTC_DCHECK(source != nullptr);
272 if (!channel_->SetAudioSend(ssrc_, track_->enabled(), &options, source)) {
273 LOG(LS_ERROR) << "SetAudioSend: ssrc is incorrect: " << ssrc_;
274 }
275}
276
277void AudioRtpSender::ClearAudioSend() {
278 RTC_DCHECK(ssrc_ != 0);
279 RTC_DCHECK(!stopped_);
280 if (!channel_) {
281 LOG(LS_WARNING) << "ClearAudioSend: No audio channel exists.";
282 return;
283 }
284 cricket::AudioOptions options;
285 if (!channel_->SetAudioSend(ssrc_, false, &options, nullptr)) {
286 LOG(LS_WARNING) << "ClearAudioSend: ssrc is incorrect: " << ssrc_;
287 }
deadbeef70ab1a12015-09-28 16:53:55 -0700288}
289
deadbeef20cb0c12017-02-01 20:27:00 -0800290void AudioRtpSender::CreateDtmfSender() {
291 // Should be on signaling thread.
292 // TODO(deadbeef): Add thread checking to RtpSender/RtpReceiver
293 // implementations.
294 rtc::scoped_refptr<DtmfSenderInterface> sender(
295 DtmfSender::Create(track_, rtc::Thread::Current(), this));
296 if (!sender.get()) {
297 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create.";
298 RTC_NOTREACHED();
299 }
300 dtmf_sender_proxy_ =
301 DtmfSenderProxy::Create(rtc::Thread::Current(), sender.get());
302}
303
deadbeef70ab1a12015-09-28 16:53:55 -0700304VideoRtpSender::VideoRtpSender(VideoTrackInterface* track,
Steve Anton8ffb9c32017-08-31 15:45:38 -0700305 const std::vector<std::string>& stream_ids,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700306 cricket::VideoChannel* channel)
deadbeef70ab1a12015-09-28 16:53:55 -0700307 : id_(track->id()),
Steve Anton8ffb9c32017-08-31 15:45:38 -0700308 stream_ids_({stream_ids}),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700309 channel_(channel),
deadbeeffac06552015-11-25 11:26:01 -0800310 track_(track),
pbos5214a0a2016-12-16 15:39:11 -0800311 cached_track_enabled_(track->enabled()),
312 cached_track_content_hint_(track->content_hint()) {
Steve Anton8ffb9c32017-08-31 15:45:38 -0700313 // TODO(steveanton): Relax this constraint once more Unified Plan work is
314 // done.
315 RTC_CHECK(stream_ids_.size() == 1U);
deadbeef70ab1a12015-09-28 16:53:55 -0700316 track_->RegisterObserver(this);
deadbeef70ab1a12015-09-28 16:53:55 -0700317}
318
deadbeefe1f9d832016-01-14 15:35:42 -0800319VideoRtpSender::VideoRtpSender(VideoTrackInterface* track,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700320 cricket::VideoChannel* channel)
deadbeefe1f9d832016-01-14 15:35:42 -0800321 : id_(track->id()),
Steve Anton8ffb9c32017-08-31 15:45:38 -0700322 // TODO(steveanton): With Unified Plan this should be empty.
323 stream_ids_({rtc::CreateRandomUuid()}),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700324 channel_(channel),
deadbeefe1f9d832016-01-14 15:35:42 -0800325 track_(track),
pbos5214a0a2016-12-16 15:39:11 -0800326 cached_track_enabled_(track->enabled()),
327 cached_track_content_hint_(track->content_hint()) {
deadbeefe1f9d832016-01-14 15:35:42 -0800328 track_->RegisterObserver(this);
329}
330
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700331VideoRtpSender::VideoRtpSender(cricket::VideoChannel* channel)
deadbeeffac06552015-11-25 11:26:01 -0800332 : id_(rtc::CreateRandomUuid()),
Steve Anton8ffb9c32017-08-31 15:45:38 -0700333 // TODO(steveanton): With Unified Plan this should be empty.
334 stream_ids_({rtc::CreateRandomUuid()}),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700335 channel_(channel) {}
deadbeeffac06552015-11-25 11:26:01 -0800336
deadbeef70ab1a12015-09-28 16:53:55 -0700337VideoRtpSender::~VideoRtpSender() {
deadbeef70ab1a12015-09-28 16:53:55 -0700338 Stop();
339}
340
341void VideoRtpSender::OnChanged() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200342 TRACE_EVENT0("webrtc", "VideoRtpSender::OnChanged");
deadbeeffac06552015-11-25 11:26:01 -0800343 RTC_DCHECK(!stopped_);
pbos5214a0a2016-12-16 15:39:11 -0800344 if (cached_track_enabled_ != track_->enabled() ||
345 cached_track_content_hint_ != track_->content_hint()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700346 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 if (can_send_track()) {
349 SetVideoSend();
350 }
deadbeef70ab1a12015-09-28 16:53:55 -0700351 }
352}
353
354bool VideoRtpSender::SetTrack(MediaStreamTrackInterface* track) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200355 TRACE_EVENT0("webrtc", "VideoRtpSender::SetTrack");
deadbeeffac06552015-11-25 11:26:01 -0800356 if (stopped_) {
357 LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
358 return false;
359 }
360 if (track && track->kind() != MediaStreamTrackInterface::kVideoKind) {
deadbeef70ab1a12015-09-28 16:53:55 -0700361 LOG(LS_ERROR) << "SetTrack called on video RtpSender with " << track->kind()
362 << " track.";
363 return false;
364 }
365 VideoTrackInterface* video_track = static_cast<VideoTrackInterface*>(track);
366
367 // Detach from old track.
deadbeeffac06552015-11-25 11:26:01 -0800368 if (track_) {
369 track_->UnregisterObserver(this);
370 }
deadbeef70ab1a12015-09-28 16:53:55 -0700371
372 // Attach to new track.
deadbeeffac06552015-11-25 11:26:01 -0800373 bool prev_can_send_track = can_send_track();
deadbeef5dd42fd2016-05-02 16:20:01 -0700374 // Keep a reference to the old track to keep it alive until we call
deadbeef5a4a75a2016-06-02 16:23:38 -0700375 // SetVideoSend.
deadbeef5dd42fd2016-05-02 16:20:01 -0700376 rtc::scoped_refptr<VideoTrackInterface> old_track = track_;
deadbeef70ab1a12015-09-28 16:53:55 -0700377 track_ = video_track;
deadbeeffac06552015-11-25 11:26:01 -0800378 if (track_) {
379 cached_track_enabled_ = track_->enabled();
pbos5214a0a2016-12-16 15:39:11 -0800380 cached_track_content_hint_ = track_->content_hint();
deadbeeffac06552015-11-25 11:26:01 -0800381 track_->RegisterObserver(this);
382 }
383
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700384 // Update video channel.
deadbeeffac06552015-11-25 11:26:01 -0800385 if (can_send_track()) {
deadbeeffac06552015-11-25 11:26:01 -0800386 SetVideoSend();
387 } else if (prev_can_send_track) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700388 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800389 }
deadbeef70ab1a12015-09-28 16:53:55 -0700390 return true;
391}
392
deadbeefa601f5c2016-06-06 14:27:39 -0700393RtpParameters VideoRtpSender::GetParameters() const {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700394 if (!channel_ || stopped_) {
395 return RtpParameters();
396 }
397 return channel_->GetRtpSendParameters(ssrc_);
deadbeefa601f5c2016-06-06 14:27:39 -0700398}
399
400bool VideoRtpSender::SetParameters(const RtpParameters& parameters) {
401 TRACE_EVENT0("webrtc", "VideoRtpSender::SetParameters");
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700402 if (!channel_ || stopped_) {
403 return false;
404 }
405 return channel_->SetRtpSendParameters(ssrc_, parameters);
deadbeefa601f5c2016-06-06 14:27:39 -0700406}
407
deadbeef20cb0c12017-02-01 20:27:00 -0800408rtc::scoped_refptr<DtmfSenderInterface> VideoRtpSender::GetDtmfSender() const {
409 LOG(LS_ERROR) << "Tried to get DTMF sender from video sender.";
410 return nullptr;
411}
412
deadbeeffac06552015-11-25 11:26:01 -0800413void VideoRtpSender::SetSsrc(uint32_t ssrc) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200414 TRACE_EVENT0("webrtc", "VideoRtpSender::SetSsrc");
deadbeeffac06552015-11-25 11:26:01 -0800415 if (stopped_ || ssrc == ssrc_) {
416 return;
417 }
418 // If we are already sending with a particular SSRC, stop sending.
419 if (can_send_track()) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700420 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800421 }
422 ssrc_ = ssrc;
423 if (can_send_track()) {
deadbeeffac06552015-11-25 11:26:01 -0800424 SetVideoSend();
425 }
426}
427
deadbeef70ab1a12015-09-28 16:53:55 -0700428void VideoRtpSender::Stop() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200429 TRACE_EVENT0("webrtc", "VideoRtpSender::Stop");
deadbeef70ab1a12015-09-28 16:53:55 -0700430 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800431 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700432 return;
433 }
deadbeeffac06552015-11-25 11:26:01 -0800434 if (track_) {
435 track_->UnregisterObserver(this);
436 }
437 if (can_send_track()) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700438 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800439 }
440 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700441}
442
deadbeeffac06552015-11-25 11:26:01 -0800443void VideoRtpSender::SetVideoSend() {
kwibergee89e782017-08-09 17:22:01 -0700444 RTC_DCHECK(!stopped_);
445 RTC_DCHECK(can_send_track());
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700446 if (!channel_) {
447 LOG(LS_ERROR) << "SetVideoSend: No video channel exists.";
448 return;
449 }
perkj0d3eef22016-03-09 02:39:17 +0100450 cricket::VideoOptions options;
perkja3ede6c2016-03-08 01:27:48 +0100451 VideoTrackSourceInterface* source = track_->GetSource();
perkj0d3eef22016-03-09 02:39:17 +0100452 if (source) {
453 options.is_screencast = rtc::Optional<bool>(source->is_screencast());
Perc0d31e92016-03-31 17:23:39 +0200454 options.video_noise_reduction = source->needs_denoising();
deadbeef70ab1a12015-09-28 16:53:55 -0700455 }
pbos5214a0a2016-12-16 15:39:11 -0800456 switch (cached_track_content_hint_) {
457 case VideoTrackInterface::ContentHint::kNone:
458 break;
459 case VideoTrackInterface::ContentHint::kFluid:
460 options.is_screencast = rtc::Optional<bool>(false);
461 break;
462 case VideoTrackInterface::ContentHint::kDetailed:
463 options.is_screencast = rtc::Optional<bool>(true);
464 break;
465 }
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700466 if (!channel_->SetVideoSend(ssrc_, track_->enabled(), &options, track_)) {
nisseeb4ca4e2017-01-12 02:24:27 -0800467 RTC_NOTREACHED();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700468 }
deadbeef5a4a75a2016-06-02 16:23:38 -0700469}
470
471void VideoRtpSender::ClearVideoSend() {
472 RTC_DCHECK(ssrc_ != 0);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700473 RTC_DCHECK(!stopped_);
474 if (!channel_) {
475 LOG(LS_WARNING) << "SetVideoSend: No video channel exists.";
476 return;
477 }
478 // Allow SetVideoSend to fail since |enable| is false and |source| is null.
479 // This the normal case when the underlying media channel has already been
480 // deleted.
481 channel_->SetVideoSend(ssrc_, false, nullptr, nullptr);
deadbeef70ab1a12015-09-28 16:53:55 -0700482}
483
484} // namespace webrtc