blob: 7c857642793c706e587da1d7dc728d0c6b70dd28 [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 Anton47136dd2018-01-12 10:49:35 -080060AudioRtpSender::AudioRtpSender(rtc::Thread* worker_thread,
61 StatsCollector* stats)
62 : AudioRtpSender(worker_thread, nullptr, {rtc::CreateRandomUuid()}, stats) {
63}
deadbeef70ab1a12015-09-28 16:53:55 -070064
Steve Anton47136dd2018-01-12 10:49:35 -080065AudioRtpSender::AudioRtpSender(rtc::Thread* worker_thread,
66 rtc::scoped_refptr<AudioTrackInterface> track,
Steve Anton02ee47c2018-01-10 16:26:06 -080067 const std::vector<std::string>& stream_labels,
deadbeefe1f9d832016-01-14 15:35:42 -080068 StatsCollector* stats)
Steve Anton47136dd2018-01-12 10:49:35 -080069 : worker_thread_(worker_thread),
70 id_(track ? track->id() : rtc::CreateRandomUuid()),
Steve Anton02ee47c2018-01-10 16:26:06 -080071 stream_ids_(stream_labels),
deadbeefe1f9d832016-01-14 15:35:42 -080072 stats_(stats),
73 track_(track),
Steve Anton02ee47c2018-01-10 16:26:06 -080074 dtmf_sender_proxy_(DtmfSenderProxy::Create(
75 rtc::Thread::Current(),
76 DtmfSender::Create(track_, rtc::Thread::Current(), this))),
77 cached_track_enabled_(track ? track->enabled() : false),
Harald Alvestrandc72af932018-01-11 17:18:19 +010078 sink_adapter_(new LocalAudioSinkAdapter()),
79 attachment_id_(track ? GenerateUniqueId() : 0) {
Steve Anton47136dd2018-01-12 10:49:35 -080080 RTC_DCHECK(worker_thread);
Steve Anton02ee47c2018-01-10 16:26:06 -080081 // TODO(bugs.webrtc.org/7932): Remove once zero or multiple streams are
82 // supported.
83 RTC_DCHECK_EQ(stream_labels.size(), 1u);
84 if (track_) {
85 track_->RegisterObserver(this);
86 track_->AddSink(sink_adapter_.get());
87 }
deadbeef20cb0c12017-02-01 20:27:00 -080088}
deadbeeffac06552015-11-25 11:26:01 -080089
deadbeef70ab1a12015-09-28 16:53:55 -070090AudioRtpSender::~AudioRtpSender() {
deadbeef20cb0c12017-02-01 20:27:00 -080091 // For DtmfSender.
92 SignalDestroyed();
deadbeef70ab1a12015-09-28 16:53:55 -070093 Stop();
94}
95
deadbeef20cb0c12017-02-01 20:27:00 -080096bool AudioRtpSender::CanInsertDtmf() {
Steve Anton47136dd2018-01-12 10:49:35 -080097 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010098 RTC_LOG(LS_ERROR) << "CanInsertDtmf: No audio channel exists.";
deadbeef20cb0c12017-02-01 20:27:00 -080099 return false;
100 }
101 // Check that this RTP sender is active (description has been applied that
102 // matches an SSRC to its ID).
103 if (!ssrc_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100104 RTC_LOG(LS_ERROR) << "CanInsertDtmf: Sender does not have SSRC.";
deadbeef20cb0c12017-02-01 20:27:00 -0800105 return false;
106 }
Steve Anton47136dd2018-01-12 10:49:35 -0800107 return worker_thread_->Invoke<bool>(
108 RTC_FROM_HERE, [&] { return media_channel_->CanInsertDtmf(); });
deadbeef20cb0c12017-02-01 20:27:00 -0800109}
110
111bool AudioRtpSender::InsertDtmf(int code, int duration) {
Steve Anton47136dd2018-01-12 10:49:35 -0800112 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100113 RTC_LOG(LS_ERROR) << "CanInsertDtmf: No audio channel exists.";
deadbeef20cb0c12017-02-01 20:27:00 -0800114 return false;
115 }
116 if (!ssrc_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100117 RTC_LOG(LS_ERROR) << "CanInsertDtmf: Sender does not have SSRC.";
deadbeef20cb0c12017-02-01 20:27:00 -0800118 return false;
119 }
Steve Anton47136dd2018-01-12 10:49:35 -0800120 bool success = worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
121 return media_channel_->InsertDtmf(ssrc_, code, duration);
122 });
123 if (!success) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100124 RTC_LOG(LS_ERROR) << "Failed to insert DTMF to channel.";
deadbeef20cb0c12017-02-01 20:27:00 -0800125 }
Steve Anton47136dd2018-01-12 10:49:35 -0800126 return success;
deadbeef20cb0c12017-02-01 20:27:00 -0800127}
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_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100147 RTC_LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
deadbeeffac06552015-11-25 11:26:01 -0800148 return false;
149 }
150 if (track && track->kind() != MediaStreamTrackInterface::kAudioKind) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100151 RTC_LOG(LS_ERROR) << "SetTrack called on audio RtpSender with "
152 << track->kind() << " track.";
deadbeef70ab1a12015-09-28 16:53:55 -0700153 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 }
Harald Alvestrandc72af932018-01-11 17:18:19 +0100188 attachment_id_ = GenerateUniqueId();
deadbeef70ab1a12015-09-28 16:53:55 -0700189 return true;
190}
191
deadbeefa601f5c2016-06-06 14:27:39 -0700192RtpParameters AudioRtpSender::GetParameters() const {
Steve Anton47136dd2018-01-12 10:49:35 -0800193 if (!media_channel_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700194 return RtpParameters();
195 }
Steve Anton47136dd2018-01-12 10:49:35 -0800196 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
197 return media_channel_->GetRtpSendParameters(ssrc_);
198 });
deadbeefa601f5c2016-06-06 14:27:39 -0700199}
200
201bool AudioRtpSender::SetParameters(const RtpParameters& parameters) {
202 TRACE_EVENT0("webrtc", "AudioRtpSender::SetParameters");
Steve Anton47136dd2018-01-12 10:49:35 -0800203 if (!media_channel_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700204 return false;
205 }
Steve Anton47136dd2018-01-12 10:49:35 -0800206 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
207 return media_channel_->SetRtpSendParameters(ssrc_, parameters);
208 });
deadbeefa601f5c2016-06-06 14:27:39 -0700209}
210
deadbeef20cb0c12017-02-01 20:27:00 -0800211rtc::scoped_refptr<DtmfSenderInterface> AudioRtpSender::GetDtmfSender() const {
212 return dtmf_sender_proxy_;
213}
214
deadbeeffac06552015-11-25 11:26:01 -0800215void AudioRtpSender::SetSsrc(uint32_t ssrc) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200216 TRACE_EVENT0("webrtc", "AudioRtpSender::SetSsrc");
deadbeeffac06552015-11-25 11:26:01 -0800217 if (stopped_ || ssrc == ssrc_) {
218 return;
219 }
220 // If we are already sending with a particular SSRC, stop sending.
221 if (can_send_track()) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700222 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800223 if (stats_) {
224 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
225 }
226 }
227 ssrc_ = ssrc;
228 if (can_send_track()) {
229 SetAudioSend();
230 if (stats_) {
231 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
232 }
233 }
234}
235
deadbeef70ab1a12015-09-28 16:53:55 -0700236void AudioRtpSender::Stop() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200237 TRACE_EVENT0("webrtc", "AudioRtpSender::Stop");
deadbeef70ab1a12015-09-28 16:53:55 -0700238 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800239 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700240 return;
241 }
deadbeeffac06552015-11-25 11:26:01 -0800242 if (track_) {
243 track_->RemoveSink(sink_adapter_.get());
244 track_->UnregisterObserver(this);
245 }
246 if (can_send_track()) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700247 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800248 if (stats_) {
249 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
250 }
251 }
252 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700253}
254
deadbeeffac06552015-11-25 11:26:01 -0800255void AudioRtpSender::SetAudioSend() {
kwibergee89e782017-08-09 17:22:01 -0700256 RTC_DCHECK(!stopped_);
257 RTC_DCHECK(can_send_track());
Steve Anton47136dd2018-01-12 10:49:35 -0800258 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100259 RTC_LOG(LS_ERROR) << "SetAudioSend: No audio channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700260 return;
261 }
deadbeef70ab1a12015-09-28 16:53:55 -0700262 cricket::AudioOptions options;
agouaillardb11fb252017-02-03 06:37:05 -0800263#if !defined(WEBRTC_CHROMIUM_BUILD) && !defined(WEBRTC_WEBKIT_BUILD)
Tommi3c169782016-01-21 16:12:17 +0100264 // TODO(tommi): Remove this hack when we move CreateAudioSource out of
265 // PeerConnection. This is a bit of a strange way to apply local audio
266 // options since it is also applied to all streams/channels, local or remote.
tommi6eca7e32015-12-15 04:27:11 -0800267 if (track_->enabled() && track_->GetSource() &&
268 !track_->GetSource()->remote()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700269 // TODO(xians): Remove this static_cast since we should be able to connect
deadbeeffac06552015-11-25 11:26:01 -0800270 // a remote audio track to a peer connection.
deadbeef70ab1a12015-09-28 16:53:55 -0700271 options = static_cast<LocalAudioSource*>(track_->GetSource())->options();
272 }
Tommi3c169782016-01-21 16:12:17 +0100273#endif
deadbeef70ab1a12015-09-28 16:53:55 -0700274
Steve Anton47136dd2018-01-12 10:49:35 -0800275 // |track_->enabled()| hops to the signaling thread, so call it before we hop
276 // to the worker thread or else it will deadlock.
277 bool track_enabled = track_->enabled();
278 bool success = worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
279 return media_channel_->SetAudioSend(ssrc_, track_enabled, &options,
280 sink_adapter_.get());
281 });
282 if (!success) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100283 RTC_LOG(LS_ERROR) << "SetAudioSend: ssrc is incorrect: " << ssrc_;
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700284 }
285}
286
287void AudioRtpSender::ClearAudioSend() {
288 RTC_DCHECK(ssrc_ != 0);
289 RTC_DCHECK(!stopped_);
Steve Anton47136dd2018-01-12 10:49:35 -0800290 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100291 RTC_LOG(LS_WARNING) << "ClearAudioSend: No audio channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700292 return;
293 }
294 cricket::AudioOptions options;
Steve Anton47136dd2018-01-12 10:49:35 -0800295 bool success = worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
296 return media_channel_->SetAudioSend(ssrc_, false, &options, nullptr);
297 });
298 if (!success) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100299 RTC_LOG(LS_WARNING) << "ClearAudioSend: ssrc is incorrect: " << ssrc_;
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700300 }
deadbeef70ab1a12015-09-28 16:53:55 -0700301}
302
Steve Anton47136dd2018-01-12 10:49:35 -0800303VideoRtpSender::VideoRtpSender(rtc::Thread* worker_thread)
304 : VideoRtpSender(worker_thread, nullptr, {rtc::CreateRandomUuid()}) {}
Steve Anton02ee47c2018-01-10 16:26:06 -0800305
Steve Anton47136dd2018-01-12 10:49:35 -0800306VideoRtpSender::VideoRtpSender(rtc::Thread* worker_thread,
307 rtc::scoped_refptr<VideoTrackInterface> track,
Steve Anton02ee47c2018-01-10 16:26:06 -0800308 const std::vector<std::string>& stream_labels)
Steve Anton47136dd2018-01-12 10:49:35 -0800309 : worker_thread_(worker_thread),
310 id_(track ? track->id() : rtc::CreateRandomUuid()),
Steve Anton02ee47c2018-01-10 16:26:06 -0800311 stream_ids_(stream_labels),
312 track_(track),
313 cached_track_enabled_(track ? track->enabled() : false),
Steve Anton47136dd2018-01-12 10:49:35 -0800314 cached_track_content_hint_(
315 track ? track->content_hint()
316 : VideoTrackInterface::ContentHint::kNone),
Harald Alvestrandc72af932018-01-11 17:18:19 +0100317 attachment_id_(track ? GenerateUniqueId() : 0) {
Steve Anton47136dd2018-01-12 10:49:35 -0800318 RTC_DCHECK(worker_thread);
Steve Anton02ee47c2018-01-10 16:26:06 -0800319 // TODO(bugs.webrtc.org/7932): Remove once zero or multiple streams are
320 // supported.
321 RTC_DCHECK_EQ(stream_labels.size(), 1u);
322 if (track_) {
323 track_->RegisterObserver(this);
deadbeef20cb0c12017-02-01 20:27:00 -0800324 }
deadbeef20cb0c12017-02-01 20:27:00 -0800325}
326
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_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100347 RTC_LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
deadbeeffac06552015-11-25 11:26:01 -0800348 return false;
349 }
350 if (track && track->kind() != MediaStreamTrackInterface::kVideoKind) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100351 RTC_LOG(LS_ERROR) << "SetTrack called on video RtpSender with "
352 << track->kind() << " track.";
deadbeef70ab1a12015-09-28 16:53:55 -0700353 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 }
Harald Alvestrandc72af932018-01-11 17:18:19 +0100380 attachment_id_ = GenerateUniqueId();
deadbeef70ab1a12015-09-28 16:53:55 -0700381 return true;
382}
383
deadbeefa601f5c2016-06-06 14:27:39 -0700384RtpParameters VideoRtpSender::GetParameters() const {
Steve Anton47136dd2018-01-12 10:49:35 -0800385 if (!media_channel_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700386 return RtpParameters();
387 }
Steve Anton47136dd2018-01-12 10:49:35 -0800388 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
389 return media_channel_->GetRtpSendParameters(ssrc_);
390 });
deadbeefa601f5c2016-06-06 14:27:39 -0700391}
392
393bool VideoRtpSender::SetParameters(const RtpParameters& parameters) {
394 TRACE_EVENT0("webrtc", "VideoRtpSender::SetParameters");
Steve Anton47136dd2018-01-12 10:49:35 -0800395 if (!media_channel_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700396 return false;
397 }
Steve Anton47136dd2018-01-12 10:49:35 -0800398 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
399 return media_channel_->SetRtpSendParameters(ssrc_, parameters);
400 });
deadbeefa601f5c2016-06-06 14:27:39 -0700401}
402
deadbeef20cb0c12017-02-01 20:27:00 -0800403rtc::scoped_refptr<DtmfSenderInterface> VideoRtpSender::GetDtmfSender() const {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100404 RTC_LOG(LS_ERROR) << "Tried to get DTMF sender from video sender.";
deadbeef20cb0c12017-02-01 20:27:00 -0800405 return nullptr;
406}
407
deadbeeffac06552015-11-25 11:26:01 -0800408void VideoRtpSender::SetSsrc(uint32_t ssrc) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200409 TRACE_EVENT0("webrtc", "VideoRtpSender::SetSsrc");
deadbeeffac06552015-11-25 11:26:01 -0800410 if (stopped_ || ssrc == ssrc_) {
411 return;
412 }
413 // If we are already sending with a particular SSRC, stop sending.
414 if (can_send_track()) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700415 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800416 }
417 ssrc_ = ssrc;
418 if (can_send_track()) {
deadbeeffac06552015-11-25 11:26:01 -0800419 SetVideoSend();
420 }
421}
422
deadbeef70ab1a12015-09-28 16:53:55 -0700423void VideoRtpSender::Stop() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200424 TRACE_EVENT0("webrtc", "VideoRtpSender::Stop");
deadbeef70ab1a12015-09-28 16:53:55 -0700425 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800426 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700427 return;
428 }
deadbeeffac06552015-11-25 11:26:01 -0800429 if (track_) {
430 track_->UnregisterObserver(this);
431 }
432 if (can_send_track()) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700433 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800434 }
435 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700436}
437
deadbeeffac06552015-11-25 11:26:01 -0800438void VideoRtpSender::SetVideoSend() {
kwibergee89e782017-08-09 17:22:01 -0700439 RTC_DCHECK(!stopped_);
440 RTC_DCHECK(can_send_track());
Steve Anton47136dd2018-01-12 10:49:35 -0800441 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100442 RTC_LOG(LS_ERROR) << "SetVideoSend: No video channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700443 return;
444 }
perkj0d3eef22016-03-09 02:39:17 +0100445 cricket::VideoOptions options;
perkja3ede6c2016-03-08 01:27:48 +0100446 VideoTrackSourceInterface* source = track_->GetSource();
perkj0d3eef22016-03-09 02:39:17 +0100447 if (source) {
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100448 options.is_screencast = source->is_screencast();
Perc0d31e92016-03-31 17:23:39 +0200449 options.video_noise_reduction = source->needs_denoising();
deadbeef70ab1a12015-09-28 16:53:55 -0700450 }
pbos5214a0a2016-12-16 15:39:11 -0800451 switch (cached_track_content_hint_) {
452 case VideoTrackInterface::ContentHint::kNone:
453 break;
454 case VideoTrackInterface::ContentHint::kFluid:
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100455 options.is_screencast = false;
pbos5214a0a2016-12-16 15:39:11 -0800456 break;
457 case VideoTrackInterface::ContentHint::kDetailed:
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100458 options.is_screencast = true;
pbos5214a0a2016-12-16 15:39:11 -0800459 break;
460 }
Steve Anton47136dd2018-01-12 10:49:35 -0800461 // |track_->enabled()| hops to the signaling thread, so call it before we hop
462 // to the worker thread or else it will deadlock.
463 bool track_enabled = track_->enabled();
464 bool success = worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
465 return media_channel_->SetVideoSend(ssrc_, track_enabled, &options, track_);
466 });
467 RTC_DCHECK(success);
deadbeef5a4a75a2016-06-02 16:23:38 -0700468}
469
470void VideoRtpSender::ClearVideoSend() {
471 RTC_DCHECK(ssrc_ != 0);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700472 RTC_DCHECK(!stopped_);
Steve Anton47136dd2018-01-12 10:49:35 -0800473 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100474 RTC_LOG(LS_WARNING) << "SetVideoSend: No video channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700475 return;
476 }
477 // Allow SetVideoSend to fail since |enable| is false and |source| is null.
478 // This the normal case when the underlying media channel has already been
479 // deleted.
Steve Anton47136dd2018-01-12 10:49:35 -0800480 worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
481 return media_channel_->SetVideoSend(ssrc_, false, nullptr, nullptr);
482 });
deadbeef70ab1a12015-09-28 16:53:55 -0700483}
484
485} // namespace webrtc