blob: 5cfbb1363767996d6141cdda2a11defe3da49ac5 [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"
Steve Anton2d8609c2018-01-23 16:38:46 -080017#include "pc/statscollector.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "rtc_base/checks.h"
19#include "rtc_base/helpers.h"
20#include "rtc_base/trace_event.h"
deadbeef70ab1a12015-09-28 16:53:55 -070021
22namespace webrtc {
23
Harald Alvestrandc72af932018-01-11 17:18:19 +010024namespace {
25
26// This function is only expected to be called on the signalling thread.
27int GenerateUniqueId() {
28 static int g_unique_id = 0;
29
30 return ++g_unique_id;
31}
32
33} // namespace
34
deadbeef70ab1a12015-09-28 16:53:55 -070035LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(nullptr) {}
36
37LocalAudioSinkAdapter::~LocalAudioSinkAdapter() {
38 rtc::CritScope lock(&lock_);
39 if (sink_)
40 sink_->OnClose();
41}
42
43void LocalAudioSinkAdapter::OnData(const void* audio_data,
44 int bits_per_sample,
45 int sample_rate,
Peter Kasting69558702016-01-12 16:26:35 -080046 size_t number_of_channels,
deadbeef70ab1a12015-09-28 16:53:55 -070047 size_t number_of_frames) {
48 rtc::CritScope lock(&lock_);
49 if (sink_) {
50 sink_->OnData(audio_data, bits_per_sample, sample_rate, number_of_channels,
51 number_of_frames);
52 }
53}
54
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -080055void LocalAudioSinkAdapter::SetSink(cricket::AudioSource::Sink* sink) {
deadbeef70ab1a12015-09-28 16:53:55 -070056 rtc::CritScope lock(&lock_);
nisseede5da42017-01-12 05:15:36 -080057 RTC_DCHECK(!sink || !sink_);
deadbeef70ab1a12015-09-28 16:53:55 -070058 sink_ = sink;
59}
60
Steve Anton47136dd2018-01-12 10:49:35 -080061AudioRtpSender::AudioRtpSender(rtc::Thread* worker_thread,
62 StatsCollector* stats)
63 : AudioRtpSender(worker_thread, nullptr, {rtc::CreateRandomUuid()}, stats) {
64}
deadbeef70ab1a12015-09-28 16:53:55 -070065
Steve Anton47136dd2018-01-12 10:49:35 -080066AudioRtpSender::AudioRtpSender(rtc::Thread* worker_thread,
67 rtc::scoped_refptr<AudioTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -080068 const std::vector<std::string>& stream_ids,
deadbeefe1f9d832016-01-14 15:35:42 -080069 StatsCollector* stats)
Steve Anton47136dd2018-01-12 10:49:35 -080070 : worker_thread_(worker_thread),
71 id_(track ? track->id() : rtc::CreateRandomUuid()),
Seth Hampson845e8782018-03-02 11:34:10 -080072 stream_ids_(stream_ids),
deadbeefe1f9d832016-01-14 15:35:42 -080073 stats_(stats),
74 track_(track),
Steve Anton02ee47c2018-01-10 16:26:06 -080075 dtmf_sender_proxy_(DtmfSenderProxy::Create(
76 rtc::Thread::Current(),
77 DtmfSender::Create(track_, rtc::Thread::Current(), this))),
78 cached_track_enabled_(track ? track->enabled() : false),
Harald Alvestrandc72af932018-01-11 17:18:19 +010079 sink_adapter_(new LocalAudioSinkAdapter()),
80 attachment_id_(track ? GenerateUniqueId() : 0) {
Steve Anton47136dd2018-01-12 10:49:35 -080081 RTC_DCHECK(worker_thread);
Steve Anton02ee47c2018-01-10 16:26:06 -080082 if (track_) {
83 track_->RegisterObserver(this);
84 track_->AddSink(sink_adapter_.get());
85 }
deadbeef20cb0c12017-02-01 20:27:00 -080086}
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() {
Steve Anton47136dd2018-01-12 10:49:35 -080095 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010096 RTC_LOG(LS_ERROR) << "CanInsertDtmf: No audio channel exists.";
deadbeef20cb0c12017-02-01 20:27:00 -080097 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_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100102 RTC_LOG(LS_ERROR) << "CanInsertDtmf: Sender does not have SSRC.";
deadbeef20cb0c12017-02-01 20:27:00 -0800103 return false;
104 }
Steve Anton47136dd2018-01-12 10:49:35 -0800105 return worker_thread_->Invoke<bool>(
106 RTC_FROM_HERE, [&] { return media_channel_->CanInsertDtmf(); });
deadbeef20cb0c12017-02-01 20:27:00 -0800107}
108
109bool AudioRtpSender::InsertDtmf(int code, int duration) {
Steve Anton47136dd2018-01-12 10:49:35 -0800110 if (!media_channel_) {
Jonas Olsson45cc8902018-02-13 10:37:07 +0100111 RTC_LOG(LS_ERROR) << "InsertDtmf: No audio channel exists.";
deadbeef20cb0c12017-02-01 20:27:00 -0800112 return false;
113 }
114 if (!ssrc_) {
Jonas Olsson45cc8902018-02-13 10:37:07 +0100115 RTC_LOG(LS_ERROR) << "InsertDtmf: Sender does not have SSRC.";
deadbeef20cb0c12017-02-01 20:27:00 -0800116 return false;
117 }
Steve Anton47136dd2018-01-12 10:49:35 -0800118 bool success = worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
119 return media_channel_->InsertDtmf(ssrc_, code, duration);
120 });
121 if (!success) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100122 RTC_LOG(LS_ERROR) << "Failed to insert DTMF to channel.";
deadbeef20cb0c12017-02-01 20:27:00 -0800123 }
Steve Anton47136dd2018-01-12 10:49:35 -0800124 return success;
deadbeef20cb0c12017-02-01 20:27:00 -0800125}
126
127sigslot::signal0<>* AudioRtpSender::GetOnDestroyedSignal() {
128 return &SignalDestroyed;
129}
130
deadbeef70ab1a12015-09-28 16:53:55 -0700131void AudioRtpSender::OnChanged() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200132 TRACE_EVENT0("webrtc", "AudioRtpSender::OnChanged");
deadbeeffac06552015-11-25 11:26:01 -0800133 RTC_DCHECK(!stopped_);
deadbeef70ab1a12015-09-28 16:53:55 -0700134 if (cached_track_enabled_ != track_->enabled()) {
135 cached_track_enabled_ = track_->enabled();
deadbeeffac06552015-11-25 11:26:01 -0800136 if (can_send_track()) {
137 SetAudioSend();
138 }
deadbeef70ab1a12015-09-28 16:53:55 -0700139 }
140}
141
142bool AudioRtpSender::SetTrack(MediaStreamTrackInterface* track) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200143 TRACE_EVENT0("webrtc", "AudioRtpSender::SetTrack");
deadbeeffac06552015-11-25 11:26:01 -0800144 if (stopped_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100145 RTC_LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
deadbeeffac06552015-11-25 11:26:01 -0800146 return false;
147 }
148 if (track && track->kind() != MediaStreamTrackInterface::kAudioKind) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100149 RTC_LOG(LS_ERROR) << "SetTrack called on audio RtpSender with "
150 << track->kind() << " track.";
deadbeef70ab1a12015-09-28 16:53:55 -0700151 return false;
152 }
153 AudioTrackInterface* audio_track = static_cast<AudioTrackInterface*>(track);
154
155 // Detach from old track.
deadbeeffac06552015-11-25 11:26:01 -0800156 if (track_) {
157 track_->RemoveSink(sink_adapter_.get());
158 track_->UnregisterObserver(this);
159 }
160
161 if (can_send_track() && stats_) {
162 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
163 }
deadbeef70ab1a12015-09-28 16:53:55 -0700164
165 // Attach to new track.
deadbeeffac06552015-11-25 11:26:01 -0800166 bool prev_can_send_track = can_send_track();
deadbeef5dd42fd2016-05-02 16:20:01 -0700167 // Keep a reference to the old track to keep it alive until we call
168 // SetAudioSend.
169 rtc::scoped_refptr<AudioTrackInterface> old_track = track_;
deadbeef70ab1a12015-09-28 16:53:55 -0700170 track_ = audio_track;
deadbeeffac06552015-11-25 11:26:01 -0800171 if (track_) {
172 cached_track_enabled_ = track_->enabled();
173 track_->RegisterObserver(this);
174 track_->AddSink(sink_adapter_.get());
175 }
176
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700177 // Update audio channel.
deadbeeffac06552015-11-25 11:26:01 -0800178 if (can_send_track()) {
179 SetAudioSend();
180 if (stats_) {
181 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
182 }
183 } else if (prev_can_send_track) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700184 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800185 }
Harald Alvestrandc72af932018-01-11 17:18:19 +0100186 attachment_id_ = GenerateUniqueId();
deadbeef70ab1a12015-09-28 16:53:55 -0700187 return true;
188}
189
deadbeefa601f5c2016-06-06 14:27:39 -0700190RtpParameters AudioRtpSender::GetParameters() const {
Steve Anton47136dd2018-01-12 10:49:35 -0800191 if (!media_channel_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700192 return RtpParameters();
193 }
Steve Anton47136dd2018-01-12 10:49:35 -0800194 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
195 return media_channel_->GetRtpSendParameters(ssrc_);
196 });
deadbeefa601f5c2016-06-06 14:27:39 -0700197}
198
Zach Steinba37b4b2018-01-23 15:02:36 -0800199RTCError AudioRtpSender::SetParameters(const RtpParameters& parameters) {
deadbeefa601f5c2016-06-06 14:27:39 -0700200 TRACE_EVENT0("webrtc", "AudioRtpSender::SetParameters");
Steve Anton47136dd2018-01-12 10:49:35 -0800201 if (!media_channel_ || stopped_) {
Zach Steinba37b4b2018-01-23 15:02:36 -0800202 return RTCError(RTCErrorType::INVALID_STATE);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700203 }
Zach Steinba37b4b2018-01-23 15:02:36 -0800204 return worker_thread_->Invoke<RTCError>(RTC_FROM_HERE, [&] {
Steve Anton47136dd2018-01-12 10:49:35 -0800205 return media_channel_->SetRtpSendParameters(ssrc_, parameters);
206 });
deadbeefa601f5c2016-06-06 14:27:39 -0700207}
208
deadbeef20cb0c12017-02-01 20:27:00 -0800209rtc::scoped_refptr<DtmfSenderInterface> AudioRtpSender::GetDtmfSender() const {
210 return dtmf_sender_proxy_;
211}
212
deadbeeffac06552015-11-25 11:26:01 -0800213void AudioRtpSender::SetSsrc(uint32_t ssrc) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200214 TRACE_EVENT0("webrtc", "AudioRtpSender::SetSsrc");
deadbeeffac06552015-11-25 11:26:01 -0800215 if (stopped_ || ssrc == ssrc_) {
216 return;
217 }
218 // If we are already sending with a particular SSRC, stop sending.
219 if (can_send_track()) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700220 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800221 if (stats_) {
222 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
223 }
224 }
225 ssrc_ = ssrc;
226 if (can_send_track()) {
227 SetAudioSend();
228 if (stats_) {
229 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
230 }
231 }
232}
233
deadbeef70ab1a12015-09-28 16:53:55 -0700234void AudioRtpSender::Stop() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200235 TRACE_EVENT0("webrtc", "AudioRtpSender::Stop");
deadbeef70ab1a12015-09-28 16:53:55 -0700236 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800237 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700238 return;
239 }
deadbeeffac06552015-11-25 11:26:01 -0800240 if (track_) {
241 track_->RemoveSink(sink_adapter_.get());
242 track_->UnregisterObserver(this);
243 }
244 if (can_send_track()) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700245 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800246 if (stats_) {
247 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
248 }
249 }
Harald Alvestrand3d976f62018-03-19 19:05:06 +0100250 media_channel_ = nullptr;
deadbeeffac06552015-11-25 11:26:01 -0800251 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700252}
253
deadbeeffac06552015-11-25 11:26:01 -0800254void AudioRtpSender::SetAudioSend() {
kwibergee89e782017-08-09 17:22:01 -0700255 RTC_DCHECK(!stopped_);
256 RTC_DCHECK(can_send_track());
Steve Anton47136dd2018-01-12 10:49:35 -0800257 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100258 RTC_LOG(LS_ERROR) << "SetAudioSend: No audio channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700259 return;
260 }
deadbeef70ab1a12015-09-28 16:53:55 -0700261 cricket::AudioOptions options;
agouaillardb11fb252017-02-03 06:37:05 -0800262#if !defined(WEBRTC_CHROMIUM_BUILD) && !defined(WEBRTC_WEBKIT_BUILD)
Tommi3c169782016-01-21 16:12:17 +0100263 // TODO(tommi): Remove this hack when we move CreateAudioSource out of
264 // PeerConnection. This is a bit of a strange way to apply local audio
265 // options since it is also applied to all streams/channels, local or remote.
tommi6eca7e32015-12-15 04:27:11 -0800266 if (track_->enabled() && track_->GetSource() &&
267 !track_->GetSource()->remote()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700268 // TODO(xians): Remove this static_cast since we should be able to connect
deadbeeffac06552015-11-25 11:26:01 -0800269 // a remote audio track to a peer connection.
deadbeef70ab1a12015-09-28 16:53:55 -0700270 options = static_cast<LocalAudioSource*>(track_->GetSource())->options();
271 }
Tommi3c169782016-01-21 16:12:17 +0100272#endif
deadbeef70ab1a12015-09-28 16:53:55 -0700273
Steve Anton47136dd2018-01-12 10:49:35 -0800274 // |track_->enabled()| hops to the signaling thread, so call it before we hop
275 // to the worker thread or else it will deadlock.
276 bool track_enabled = track_->enabled();
277 bool success = worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
278 return media_channel_->SetAudioSend(ssrc_, track_enabled, &options,
279 sink_adapter_.get());
280 });
281 if (!success) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100282 RTC_LOG(LS_ERROR) << "SetAudioSend: ssrc is incorrect: " << ssrc_;
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700283 }
284}
285
286void AudioRtpSender::ClearAudioSend() {
287 RTC_DCHECK(ssrc_ != 0);
288 RTC_DCHECK(!stopped_);
Steve Anton47136dd2018-01-12 10:49:35 -0800289 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100290 RTC_LOG(LS_WARNING) << "ClearAudioSend: No audio channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700291 return;
292 }
293 cricket::AudioOptions options;
Steve Anton47136dd2018-01-12 10:49:35 -0800294 bool success = worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
295 return media_channel_->SetAudioSend(ssrc_, false, &options, nullptr);
296 });
297 if (!success) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100298 RTC_LOG(LS_WARNING) << "ClearAudioSend: ssrc is incorrect: " << ssrc_;
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700299 }
deadbeef70ab1a12015-09-28 16:53:55 -0700300}
301
Steve Anton47136dd2018-01-12 10:49:35 -0800302VideoRtpSender::VideoRtpSender(rtc::Thread* worker_thread)
303 : VideoRtpSender(worker_thread, nullptr, {rtc::CreateRandomUuid()}) {}
Steve Anton02ee47c2018-01-10 16:26:06 -0800304
Steve Anton47136dd2018-01-12 10:49:35 -0800305VideoRtpSender::VideoRtpSender(rtc::Thread* worker_thread,
306 rtc::scoped_refptr<VideoTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800307 const std::vector<std::string>& stream_ids)
Steve Anton47136dd2018-01-12 10:49:35 -0800308 : worker_thread_(worker_thread),
309 id_(track ? track->id() : rtc::CreateRandomUuid()),
Seth Hampson845e8782018-03-02 11:34:10 -0800310 stream_ids_(stream_ids),
Steve Anton02ee47c2018-01-10 16:26:06 -0800311 track_(track),
Seth Hampson845e8782018-03-02 11:34:10 -0800312 cached_track_content_hint_(track
313 ? track->content_hint()
314 : VideoTrackInterface::ContentHint::kNone),
Harald Alvestrandc72af932018-01-11 17:18:19 +0100315 attachment_id_(track ? GenerateUniqueId() : 0) {
Steve Anton47136dd2018-01-12 10:49:35 -0800316 RTC_DCHECK(worker_thread);
Steve Anton02ee47c2018-01-10 16:26:06 -0800317 if (track_) {
318 track_->RegisterObserver(this);
deadbeef20cb0c12017-02-01 20:27:00 -0800319 }
deadbeef20cb0c12017-02-01 20:27:00 -0800320}
321
deadbeef70ab1a12015-09-28 16:53:55 -0700322VideoRtpSender::~VideoRtpSender() {
deadbeef70ab1a12015-09-28 16:53:55 -0700323 Stop();
324}
325
326void VideoRtpSender::OnChanged() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200327 TRACE_EVENT0("webrtc", "VideoRtpSender::OnChanged");
deadbeeffac06552015-11-25 11:26:01 -0800328 RTC_DCHECK(!stopped_);
Niels Möllerff40b142018-04-09 08:49:14 +0200329 if (cached_track_content_hint_ != track_->content_hint()) {
pbos5214a0a2016-12-16 15:39:11 -0800330 cached_track_content_hint_ = track_->content_hint();
deadbeeffac06552015-11-25 11:26:01 -0800331 if (can_send_track()) {
332 SetVideoSend();
333 }
deadbeef70ab1a12015-09-28 16:53:55 -0700334 }
335}
336
337bool VideoRtpSender::SetTrack(MediaStreamTrackInterface* track) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200338 TRACE_EVENT0("webrtc", "VideoRtpSender::SetTrack");
deadbeeffac06552015-11-25 11:26:01 -0800339 if (stopped_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100340 RTC_LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
deadbeeffac06552015-11-25 11:26:01 -0800341 return false;
342 }
343 if (track && track->kind() != MediaStreamTrackInterface::kVideoKind) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100344 RTC_LOG(LS_ERROR) << "SetTrack called on video RtpSender with "
345 << track->kind() << " track.";
deadbeef70ab1a12015-09-28 16:53:55 -0700346 return false;
347 }
348 VideoTrackInterface* video_track = static_cast<VideoTrackInterface*>(track);
349
350 // Detach from old track.
deadbeeffac06552015-11-25 11:26:01 -0800351 if (track_) {
352 track_->UnregisterObserver(this);
353 }
deadbeef70ab1a12015-09-28 16:53:55 -0700354
355 // Attach to new track.
deadbeeffac06552015-11-25 11:26:01 -0800356 bool prev_can_send_track = can_send_track();
deadbeef5dd42fd2016-05-02 16:20:01 -0700357 // Keep a reference to the old track to keep it alive until we call
deadbeef5a4a75a2016-06-02 16:23:38 -0700358 // SetVideoSend.
deadbeef5dd42fd2016-05-02 16:20:01 -0700359 rtc::scoped_refptr<VideoTrackInterface> old_track = track_;
deadbeef70ab1a12015-09-28 16:53:55 -0700360 track_ = video_track;
deadbeeffac06552015-11-25 11:26:01 -0800361 if (track_) {
pbos5214a0a2016-12-16 15:39:11 -0800362 cached_track_content_hint_ = track_->content_hint();
deadbeeffac06552015-11-25 11:26:01 -0800363 track_->RegisterObserver(this);
364 }
365
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700366 // Update video channel.
deadbeeffac06552015-11-25 11:26:01 -0800367 if (can_send_track()) {
deadbeeffac06552015-11-25 11:26:01 -0800368 SetVideoSend();
369 } else if (prev_can_send_track) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700370 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800371 }
Harald Alvestrandc72af932018-01-11 17:18:19 +0100372 attachment_id_ = GenerateUniqueId();
deadbeef70ab1a12015-09-28 16:53:55 -0700373 return true;
374}
375
deadbeefa601f5c2016-06-06 14:27:39 -0700376RtpParameters VideoRtpSender::GetParameters() const {
Steve Anton47136dd2018-01-12 10:49:35 -0800377 if (!media_channel_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700378 return RtpParameters();
379 }
Steve Anton47136dd2018-01-12 10:49:35 -0800380 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
381 return media_channel_->GetRtpSendParameters(ssrc_);
382 });
deadbeefa601f5c2016-06-06 14:27:39 -0700383}
384
Zach Steinba37b4b2018-01-23 15:02:36 -0800385RTCError VideoRtpSender::SetParameters(const RtpParameters& parameters) {
deadbeefa601f5c2016-06-06 14:27:39 -0700386 TRACE_EVENT0("webrtc", "VideoRtpSender::SetParameters");
Steve Anton47136dd2018-01-12 10:49:35 -0800387 if (!media_channel_ || stopped_) {
Zach Steinba37b4b2018-01-23 15:02:36 -0800388 return RTCError(RTCErrorType::INVALID_STATE);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700389 }
Zach Steinba37b4b2018-01-23 15:02:36 -0800390 return worker_thread_->Invoke<RTCError>(RTC_FROM_HERE, [&] {
Steve Anton47136dd2018-01-12 10:49:35 -0800391 return media_channel_->SetRtpSendParameters(ssrc_, parameters);
392 });
deadbeefa601f5c2016-06-06 14:27:39 -0700393}
394
deadbeef20cb0c12017-02-01 20:27:00 -0800395rtc::scoped_refptr<DtmfSenderInterface> VideoRtpSender::GetDtmfSender() const {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100396 RTC_LOG(LS_ERROR) << "Tried to get DTMF sender from video sender.";
deadbeef20cb0c12017-02-01 20:27:00 -0800397 return nullptr;
398}
399
deadbeeffac06552015-11-25 11:26:01 -0800400void VideoRtpSender::SetSsrc(uint32_t ssrc) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200401 TRACE_EVENT0("webrtc", "VideoRtpSender::SetSsrc");
deadbeeffac06552015-11-25 11:26:01 -0800402 if (stopped_ || ssrc == ssrc_) {
403 return;
404 }
405 // If we are already sending with a particular SSRC, stop sending.
406 if (can_send_track()) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700407 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800408 }
409 ssrc_ = ssrc;
410 if (can_send_track()) {
deadbeeffac06552015-11-25 11:26:01 -0800411 SetVideoSend();
412 }
413}
414
deadbeef70ab1a12015-09-28 16:53:55 -0700415void VideoRtpSender::Stop() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200416 TRACE_EVENT0("webrtc", "VideoRtpSender::Stop");
deadbeef70ab1a12015-09-28 16:53:55 -0700417 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800418 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700419 return;
420 }
deadbeeffac06552015-11-25 11:26:01 -0800421 if (track_) {
422 track_->UnregisterObserver(this);
423 }
424 if (can_send_track()) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700425 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800426 }
Harald Alvestrand3d976f62018-03-19 19:05:06 +0100427 media_channel_ = nullptr;
deadbeeffac06552015-11-25 11:26:01 -0800428 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700429}
430
deadbeeffac06552015-11-25 11:26:01 -0800431void VideoRtpSender::SetVideoSend() {
kwibergee89e782017-08-09 17:22:01 -0700432 RTC_DCHECK(!stopped_);
433 RTC_DCHECK(can_send_track());
Steve Anton47136dd2018-01-12 10:49:35 -0800434 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100435 RTC_LOG(LS_ERROR) << "SetVideoSend: No video channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700436 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) {
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100441 options.is_screencast = 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:
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100448 options.is_screencast = false;
pbos5214a0a2016-12-16 15:39:11 -0800449 break;
450 case VideoTrackInterface::ContentHint::kDetailed:
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100451 options.is_screencast = true;
pbos5214a0a2016-12-16 15:39:11 -0800452 break;
453 }
Steve Anton47136dd2018-01-12 10:49:35 -0800454 bool success = worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
Niels Möllerff40b142018-04-09 08:49:14 +0200455 return media_channel_->SetVideoSend(ssrc_, &options, track_);
Steve Anton47136dd2018-01-12 10:49:35 -0800456 });
457 RTC_DCHECK(success);
deadbeef5a4a75a2016-06-02 16:23:38 -0700458}
459
460void VideoRtpSender::ClearVideoSend() {
461 RTC_DCHECK(ssrc_ != 0);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700462 RTC_DCHECK(!stopped_);
Steve Anton47136dd2018-01-12 10:49:35 -0800463 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100464 RTC_LOG(LS_WARNING) << "SetVideoSend: No video channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700465 return;
466 }
467 // Allow SetVideoSend to fail since |enable| is false and |source| is null.
468 // This the normal case when the underlying media channel has already been
469 // deleted.
Steve Anton47136dd2018-01-12 10:49:35 -0800470 worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
Niels Möllerff40b142018-04-09 08:49:14 +0200471 return media_channel_->SetVideoSend(ssrc_, nullptr, nullptr);
Steve Anton47136dd2018-01-12 10:49:35 -0800472 });
deadbeef70ab1a12015-09-28 16:53:55 -0700473}
474
475} // namespace webrtc