blob: b2e246120f03e2a9a500b311522252079d6743de [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
Henrik Kjellander15583c12016-02-10 10:53:12 +010011#include "webrtc/api/rtpsender.h"
deadbeef6979b022015-09-24 16:47:53 -070012
Henrik Kjellander15583c12016-02-10 10:53:12 +010013#include "webrtc/api/localaudiosource.h"
perkj9e083d22016-03-20 09:38:40 -070014#include "webrtc/api/mediastreaminterface.h"
nisseede5da42017-01-12 05:15:36 -080015#include "webrtc/base/checks.h"
deadbeeffac06552015-11-25 11:26:01 -080016#include "webrtc/base/helpers.h"
Peter Boströmdabc9442016-04-11 11:45:14 +020017#include "webrtc/base/trace_event.h"
deadbeef70ab1a12015-09-28 16:53:55 -070018
19namespace webrtc {
20
21LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(nullptr) {}
22
23LocalAudioSinkAdapter::~LocalAudioSinkAdapter() {
24 rtc::CritScope lock(&lock_);
25 if (sink_)
26 sink_->OnClose();
27}
28
29void LocalAudioSinkAdapter::OnData(const void* audio_data,
30 int bits_per_sample,
31 int sample_rate,
Peter Kasting69558702016-01-12 16:26:35 -080032 size_t number_of_channels,
deadbeef70ab1a12015-09-28 16:53:55 -070033 size_t number_of_frames) {
34 rtc::CritScope lock(&lock_);
35 if (sink_) {
36 sink_->OnData(audio_data, bits_per_sample, sample_rate, number_of_channels,
37 number_of_frames);
38 }
39}
40
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -080041void LocalAudioSinkAdapter::SetSink(cricket::AudioSource::Sink* sink) {
deadbeef70ab1a12015-09-28 16:53:55 -070042 rtc::CritScope lock(&lock_);
nisseede5da42017-01-12 05:15:36 -080043 RTC_DCHECK(!sink || !sink_);
deadbeef70ab1a12015-09-28 16:53:55 -070044 sink_ = sink;
45}
46
47AudioRtpSender::AudioRtpSender(AudioTrackInterface* track,
deadbeeffac06552015-11-25 11:26:01 -080048 const std::string& stream_id,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070049 cricket::VoiceChannel* channel,
deadbeeffac06552015-11-25 11:26:01 -080050 StatsCollector* stats)
deadbeef70ab1a12015-09-28 16:53:55 -070051 : id_(track->id()),
deadbeeffac06552015-11-25 11:26:01 -080052 stream_id_(stream_id),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070053 channel_(channel),
deadbeeffac06552015-11-25 11:26:01 -080054 stats_(stats),
55 track_(track),
deadbeef70ab1a12015-09-28 16:53:55 -070056 cached_track_enabled_(track->enabled()),
57 sink_adapter_(new LocalAudioSinkAdapter()) {
58 track_->RegisterObserver(this);
59 track_->AddSink(sink_adapter_.get());
deadbeef70ab1a12015-09-28 16:53:55 -070060}
61
deadbeefe1f9d832016-01-14 15:35:42 -080062AudioRtpSender::AudioRtpSender(AudioTrackInterface* track,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070063 cricket::VoiceChannel* channel,
deadbeefe1f9d832016-01-14 15:35:42 -080064 StatsCollector* stats)
65 : id_(track->id()),
66 stream_id_(rtc::CreateRandomUuid()),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070067 channel_(channel),
deadbeefe1f9d832016-01-14 15:35:42 -080068 stats_(stats),
69 track_(track),
70 cached_track_enabled_(track->enabled()),
71 sink_adapter_(new LocalAudioSinkAdapter()) {
deadbeefe1f9d832016-01-14 15:35:42 -080072 track_->RegisterObserver(this);
73 track_->AddSink(sink_adapter_.get());
74}
75
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070076AudioRtpSender::AudioRtpSender(cricket::VoiceChannel* channel,
deadbeeffac06552015-11-25 11:26:01 -080077 StatsCollector* stats)
78 : id_(rtc::CreateRandomUuid()),
79 stream_id_(rtc::CreateRandomUuid()),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070080 channel_(channel),
deadbeeffac06552015-11-25 11:26:01 -080081 stats_(stats),
82 sink_adapter_(new LocalAudioSinkAdapter()) {}
83
deadbeef70ab1a12015-09-28 16:53:55 -070084AudioRtpSender::~AudioRtpSender() {
deadbeef70ab1a12015-09-28 16:53:55 -070085 Stop();
86}
87
88void AudioRtpSender::OnChanged() {
Peter Boströmdabc9442016-04-11 11:45:14 +020089 TRACE_EVENT0("webrtc", "AudioRtpSender::OnChanged");
deadbeeffac06552015-11-25 11:26:01 -080090 RTC_DCHECK(!stopped_);
deadbeef70ab1a12015-09-28 16:53:55 -070091 if (cached_track_enabled_ != track_->enabled()) {
92 cached_track_enabled_ = track_->enabled();
deadbeeffac06552015-11-25 11:26:01 -080093 if (can_send_track()) {
94 SetAudioSend();
95 }
deadbeef70ab1a12015-09-28 16:53:55 -070096 }
97}
98
99bool AudioRtpSender::SetTrack(MediaStreamTrackInterface* track) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200100 TRACE_EVENT0("webrtc", "AudioRtpSender::SetTrack");
deadbeeffac06552015-11-25 11:26:01 -0800101 if (stopped_) {
102 LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
103 return false;
104 }
105 if (track && track->kind() != MediaStreamTrackInterface::kAudioKind) {
deadbeef70ab1a12015-09-28 16:53:55 -0700106 LOG(LS_ERROR) << "SetTrack called on audio RtpSender with " << track->kind()
107 << " track.";
108 return false;
109 }
110 AudioTrackInterface* audio_track = static_cast<AudioTrackInterface*>(track);
111
112 // Detach from old track.
deadbeeffac06552015-11-25 11:26:01 -0800113 if (track_) {
114 track_->RemoveSink(sink_adapter_.get());
115 track_->UnregisterObserver(this);
116 }
117
118 if (can_send_track() && stats_) {
119 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
120 }
deadbeef70ab1a12015-09-28 16:53:55 -0700121
122 // Attach to new track.
deadbeeffac06552015-11-25 11:26:01 -0800123 bool prev_can_send_track = can_send_track();
deadbeef5dd42fd2016-05-02 16:20:01 -0700124 // Keep a reference to the old track to keep it alive until we call
125 // SetAudioSend.
126 rtc::scoped_refptr<AudioTrackInterface> old_track = track_;
deadbeef70ab1a12015-09-28 16:53:55 -0700127 track_ = audio_track;
deadbeeffac06552015-11-25 11:26:01 -0800128 if (track_) {
129 cached_track_enabled_ = track_->enabled();
130 track_->RegisterObserver(this);
131 track_->AddSink(sink_adapter_.get());
132 }
133
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700134 // Update audio channel.
deadbeeffac06552015-11-25 11:26:01 -0800135 if (can_send_track()) {
136 SetAudioSend();
137 if (stats_) {
138 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
139 }
140 } else if (prev_can_send_track) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700141 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800142 }
deadbeef70ab1a12015-09-28 16:53:55 -0700143 return true;
144}
145
deadbeefa601f5c2016-06-06 14:27:39 -0700146RtpParameters AudioRtpSender::GetParameters() const {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700147 if (!channel_ || stopped_) {
148 return RtpParameters();
149 }
150 return channel_->GetRtpSendParameters(ssrc_);
deadbeefa601f5c2016-06-06 14:27:39 -0700151}
152
153bool AudioRtpSender::SetParameters(const RtpParameters& parameters) {
154 TRACE_EVENT0("webrtc", "AudioRtpSender::SetParameters");
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700155 if (!channel_ || stopped_) {
156 return false;
157 }
158 return channel_->SetRtpSendParameters(ssrc_, parameters);
deadbeefa601f5c2016-06-06 14:27:39 -0700159}
160
deadbeeffac06552015-11-25 11:26:01 -0800161void AudioRtpSender::SetSsrc(uint32_t ssrc) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200162 TRACE_EVENT0("webrtc", "AudioRtpSender::SetSsrc");
deadbeeffac06552015-11-25 11:26:01 -0800163 if (stopped_ || ssrc == ssrc_) {
164 return;
165 }
166 // If we are already sending with a particular SSRC, stop sending.
167 if (can_send_track()) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700168 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800169 if (stats_) {
170 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
171 }
172 }
173 ssrc_ = ssrc;
174 if (can_send_track()) {
175 SetAudioSend();
176 if (stats_) {
177 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
178 }
179 }
180}
181
deadbeef70ab1a12015-09-28 16:53:55 -0700182void AudioRtpSender::Stop() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200183 TRACE_EVENT0("webrtc", "AudioRtpSender::Stop");
deadbeef70ab1a12015-09-28 16:53:55 -0700184 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800185 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700186 return;
187 }
deadbeeffac06552015-11-25 11:26:01 -0800188 if (track_) {
189 track_->RemoveSink(sink_adapter_.get());
190 track_->UnregisterObserver(this);
191 }
192 if (can_send_track()) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700193 ClearAudioSend();
deadbeeffac06552015-11-25 11:26:01 -0800194 if (stats_) {
195 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
196 }
197 }
198 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700199}
200
deadbeeffac06552015-11-25 11:26:01 -0800201void AudioRtpSender::SetAudioSend() {
202 RTC_DCHECK(!stopped_ && can_send_track());
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700203 if (!channel_) {
204 LOG(LS_ERROR) << "SetAudioSend: No audio channel exists.";
205 return;
206 }
deadbeef70ab1a12015-09-28 16:53:55 -0700207 cricket::AudioOptions options;
Tommi3c169782016-01-21 16:12:17 +0100208#if !defined(WEBRTC_CHROMIUM_BUILD)
209 // TODO(tommi): Remove this hack when we move CreateAudioSource out of
210 // PeerConnection. This is a bit of a strange way to apply local audio
211 // options since it is also applied to all streams/channels, local or remote.
tommi6eca7e32015-12-15 04:27:11 -0800212 if (track_->enabled() && track_->GetSource() &&
213 !track_->GetSource()->remote()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700214 // TODO(xians): Remove this static_cast since we should be able to connect
deadbeeffac06552015-11-25 11:26:01 -0800215 // a remote audio track to a peer connection.
deadbeef70ab1a12015-09-28 16:53:55 -0700216 options = static_cast<LocalAudioSource*>(track_->GetSource())->options();
217 }
Tommi3c169782016-01-21 16:12:17 +0100218#endif
deadbeef70ab1a12015-09-28 16:53:55 -0700219
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800220 cricket::AudioSource* source = sink_adapter_.get();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700221 RTC_DCHECK(source != nullptr);
222 if (!channel_->SetAudioSend(ssrc_, track_->enabled(), &options, source)) {
223 LOG(LS_ERROR) << "SetAudioSend: ssrc is incorrect: " << ssrc_;
224 }
225}
226
227void AudioRtpSender::ClearAudioSend() {
228 RTC_DCHECK(ssrc_ != 0);
229 RTC_DCHECK(!stopped_);
230 if (!channel_) {
231 LOG(LS_WARNING) << "ClearAudioSend: No audio channel exists.";
232 return;
233 }
234 cricket::AudioOptions options;
235 if (!channel_->SetAudioSend(ssrc_, false, &options, nullptr)) {
236 LOG(LS_WARNING) << "ClearAudioSend: ssrc is incorrect: " << ssrc_;
237 }
deadbeef70ab1a12015-09-28 16:53:55 -0700238}
239
240VideoRtpSender::VideoRtpSender(VideoTrackInterface* track,
deadbeeffac06552015-11-25 11:26:01 -0800241 const std::string& stream_id,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700242 cricket::VideoChannel* channel)
deadbeef70ab1a12015-09-28 16:53:55 -0700243 : id_(track->id()),
deadbeeffac06552015-11-25 11:26:01 -0800244 stream_id_(stream_id),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700245 channel_(channel),
deadbeeffac06552015-11-25 11:26:01 -0800246 track_(track),
pbos5214a0a2016-12-16 15:39:11 -0800247 cached_track_enabled_(track->enabled()),
248 cached_track_content_hint_(track->content_hint()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700249 track_->RegisterObserver(this);
deadbeef70ab1a12015-09-28 16:53:55 -0700250}
251
deadbeefe1f9d832016-01-14 15:35:42 -0800252VideoRtpSender::VideoRtpSender(VideoTrackInterface* track,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700253 cricket::VideoChannel* channel)
deadbeefe1f9d832016-01-14 15:35:42 -0800254 : id_(track->id()),
255 stream_id_(rtc::CreateRandomUuid()),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700256 channel_(channel),
deadbeefe1f9d832016-01-14 15:35:42 -0800257 track_(track),
pbos5214a0a2016-12-16 15:39:11 -0800258 cached_track_enabled_(track->enabled()),
259 cached_track_content_hint_(track->content_hint()) {
deadbeefe1f9d832016-01-14 15:35:42 -0800260 track_->RegisterObserver(this);
261}
262
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700263VideoRtpSender::VideoRtpSender(cricket::VideoChannel* channel)
deadbeeffac06552015-11-25 11:26:01 -0800264 : id_(rtc::CreateRandomUuid()),
265 stream_id_(rtc::CreateRandomUuid()),
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700266 channel_(channel) {}
deadbeeffac06552015-11-25 11:26:01 -0800267
deadbeef70ab1a12015-09-28 16:53:55 -0700268VideoRtpSender::~VideoRtpSender() {
deadbeef70ab1a12015-09-28 16:53:55 -0700269 Stop();
270}
271
272void VideoRtpSender::OnChanged() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200273 TRACE_EVENT0("webrtc", "VideoRtpSender::OnChanged");
deadbeeffac06552015-11-25 11:26:01 -0800274 RTC_DCHECK(!stopped_);
pbos5214a0a2016-12-16 15:39:11 -0800275 if (cached_track_enabled_ != track_->enabled() ||
276 cached_track_content_hint_ != track_->content_hint()) {
deadbeef70ab1a12015-09-28 16:53:55 -0700277 cached_track_enabled_ = track_->enabled();
pbos5214a0a2016-12-16 15:39:11 -0800278 cached_track_content_hint_ = track_->content_hint();
deadbeeffac06552015-11-25 11:26:01 -0800279 if (can_send_track()) {
280 SetVideoSend();
281 }
deadbeef70ab1a12015-09-28 16:53:55 -0700282 }
283}
284
285bool VideoRtpSender::SetTrack(MediaStreamTrackInterface* track) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200286 TRACE_EVENT0("webrtc", "VideoRtpSender::SetTrack");
deadbeeffac06552015-11-25 11:26:01 -0800287 if (stopped_) {
288 LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
289 return false;
290 }
291 if (track && track->kind() != MediaStreamTrackInterface::kVideoKind) {
deadbeef70ab1a12015-09-28 16:53:55 -0700292 LOG(LS_ERROR) << "SetTrack called on video RtpSender with " << track->kind()
293 << " track.";
294 return false;
295 }
296 VideoTrackInterface* video_track = static_cast<VideoTrackInterface*>(track);
297
298 // Detach from old track.
deadbeeffac06552015-11-25 11:26:01 -0800299 if (track_) {
300 track_->UnregisterObserver(this);
301 }
deadbeef70ab1a12015-09-28 16:53:55 -0700302
303 // Attach to new track.
deadbeeffac06552015-11-25 11:26:01 -0800304 bool prev_can_send_track = can_send_track();
deadbeef5dd42fd2016-05-02 16:20:01 -0700305 // Keep a reference to the old track to keep it alive until we call
deadbeef5a4a75a2016-06-02 16:23:38 -0700306 // SetVideoSend.
deadbeef5dd42fd2016-05-02 16:20:01 -0700307 rtc::scoped_refptr<VideoTrackInterface> old_track = track_;
deadbeef70ab1a12015-09-28 16:53:55 -0700308 track_ = video_track;
deadbeeffac06552015-11-25 11:26:01 -0800309 if (track_) {
310 cached_track_enabled_ = track_->enabled();
pbos5214a0a2016-12-16 15:39:11 -0800311 cached_track_content_hint_ = track_->content_hint();
deadbeeffac06552015-11-25 11:26:01 -0800312 track_->RegisterObserver(this);
313 }
314
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700315 // Update video channel.
deadbeeffac06552015-11-25 11:26:01 -0800316 if (can_send_track()) {
deadbeeffac06552015-11-25 11:26:01 -0800317 SetVideoSend();
318 } else if (prev_can_send_track) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700319 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800320 }
deadbeef70ab1a12015-09-28 16:53:55 -0700321 return true;
322}
323
deadbeefa601f5c2016-06-06 14:27:39 -0700324RtpParameters VideoRtpSender::GetParameters() const {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700325 if (!channel_ || stopped_) {
326 return RtpParameters();
327 }
328 return channel_->GetRtpSendParameters(ssrc_);
deadbeefa601f5c2016-06-06 14:27:39 -0700329}
330
331bool VideoRtpSender::SetParameters(const RtpParameters& parameters) {
332 TRACE_EVENT0("webrtc", "VideoRtpSender::SetParameters");
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700333 if (!channel_ || stopped_) {
334 return false;
335 }
336 return channel_->SetRtpSendParameters(ssrc_, parameters);
deadbeefa601f5c2016-06-06 14:27:39 -0700337}
338
deadbeeffac06552015-11-25 11:26:01 -0800339void VideoRtpSender::SetSsrc(uint32_t ssrc) {
Peter Boströmdabc9442016-04-11 11:45:14 +0200340 TRACE_EVENT0("webrtc", "VideoRtpSender::SetSsrc");
deadbeeffac06552015-11-25 11:26:01 -0800341 if (stopped_ || ssrc == ssrc_) {
342 return;
343 }
344 // If we are already sending with a particular SSRC, stop sending.
345 if (can_send_track()) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700346 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800347 }
348 ssrc_ = ssrc;
349 if (can_send_track()) {
deadbeeffac06552015-11-25 11:26:01 -0800350 SetVideoSend();
351 }
352}
353
deadbeef70ab1a12015-09-28 16:53:55 -0700354void VideoRtpSender::Stop() {
Peter Boströmdabc9442016-04-11 11:45:14 +0200355 TRACE_EVENT0("webrtc", "VideoRtpSender::Stop");
deadbeef70ab1a12015-09-28 16:53:55 -0700356 // TODO(deadbeef): Need to do more here to fully stop sending packets.
deadbeeffac06552015-11-25 11:26:01 -0800357 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700358 return;
359 }
deadbeeffac06552015-11-25 11:26:01 -0800360 if (track_) {
361 track_->UnregisterObserver(this);
362 }
363 if (can_send_track()) {
deadbeef5a4a75a2016-06-02 16:23:38 -0700364 ClearVideoSend();
deadbeeffac06552015-11-25 11:26:01 -0800365 }
366 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700367}
368
deadbeeffac06552015-11-25 11:26:01 -0800369void VideoRtpSender::SetVideoSend() {
370 RTC_DCHECK(!stopped_ && can_send_track());
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700371 if (!channel_) {
372 LOG(LS_ERROR) << "SetVideoSend: No video channel exists.";
373 return;
374 }
perkj0d3eef22016-03-09 02:39:17 +0100375 cricket::VideoOptions options;
perkja3ede6c2016-03-08 01:27:48 +0100376 VideoTrackSourceInterface* source = track_->GetSource();
perkj0d3eef22016-03-09 02:39:17 +0100377 if (source) {
378 options.is_screencast = rtc::Optional<bool>(source->is_screencast());
Perc0d31e92016-03-31 17:23:39 +0200379 options.video_noise_reduction = source->needs_denoising();
deadbeef70ab1a12015-09-28 16:53:55 -0700380 }
pbos5214a0a2016-12-16 15:39:11 -0800381 switch (cached_track_content_hint_) {
382 case VideoTrackInterface::ContentHint::kNone:
383 break;
384 case VideoTrackInterface::ContentHint::kFluid:
385 options.is_screencast = rtc::Optional<bool>(false);
386 break;
387 case VideoTrackInterface::ContentHint::kDetailed:
388 options.is_screencast = rtc::Optional<bool>(true);
389 break;
390 }
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700391 if (!channel_->SetVideoSend(ssrc_, track_->enabled(), &options, track_)) {
nisseeb4ca4e2017-01-12 02:24:27 -0800392 RTC_NOTREACHED();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700393 }
deadbeef5a4a75a2016-06-02 16:23:38 -0700394}
395
396void VideoRtpSender::ClearVideoSend() {
397 RTC_DCHECK(ssrc_ != 0);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700398 RTC_DCHECK(!stopped_);
399 if (!channel_) {
400 LOG(LS_WARNING) << "SetVideoSend: No video channel exists.";
401 return;
402 }
403 // Allow SetVideoSend to fail since |enable| is false and |source| is null.
404 // This the normal case when the underlying media channel has already been
405 // deleted.
406 channel_->SetVideoSend(ssrc_, false, nullptr, nullptr);
deadbeef70ab1a12015-09-28 16:53:55 -0700407}
408
409} // namespace webrtc