blob: 98c501c22b1f543860d11ab1108b96ce76831e05 [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/rtpreceiver.h"
deadbeef6979b022015-09-24 16:47:53 -070012
Henrik Boström9e6fd2b2017-11-21 13:41:51 +010013#include <utility>
Steve Anton36b29d12017-10-30 09:57:42 -070014#include <vector>
15
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "api/mediastreamtrackproxy.h"
17#include "api/videosourceproxy.h"
18#include "pc/audiotrack.h"
19#include "pc/videotrack.h"
20#include "rtc_base/trace_event.h"
deadbeef70ab1a12015-09-28 16:53:55 -070021
22namespace webrtc {
23
Henrik Boström9e6fd2b2017-11-21 13:41:51 +010024AudioRtpReceiver::AudioRtpReceiver(
Steve Anton60776752018-01-10 11:51:34 -080025 rtc::Thread* worker_thread,
Steve Anton9158ef62017-11-27 13:01:52 -080026 const std::string& receiver_id,
Steve Antonef65ef12018-01-10 17:15:20 -080027 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams,
Henrik Boström9e6fd2b2017-11-21 13:41:51 +010028 uint32_t ssrc,
Steve Anton60776752018-01-10 11:51:34 -080029 cricket::VoiceMediaChannel* media_channel)
30 : worker_thread_(worker_thread),
31 id_(receiver_id),
deadbeef70ab1a12015-09-28 16:53:55 -070032 ssrc_(ssrc),
perkjd61bf802016-03-24 03:16:19 -070033 track_(AudioTrackProxy::Create(
34 rtc::Thread::Current(),
Steve Anton60776752018-01-10 11:51:34 -080035 AudioTrack::Create(
36 receiver_id,
37 RemoteAudioSource::Create(worker_thread, media_channel, ssrc)))),
perkjd61bf802016-03-24 03:16:19 -070038 cached_track_enabled_(track_->enabled()) {
Steve Anton60776752018-01-10 11:51:34 -080039 RTC_DCHECK(worker_thread_);
tommi6eca7e32015-12-15 04:27:11 -080040 RTC_DCHECK(track_->GetSource()->remote());
deadbeef70ab1a12015-09-28 16:53:55 -070041 track_->RegisterObserver(this);
42 track_->GetSource()->RegisterAudioObserver(this);
Steve Antonef65ef12018-01-10 17:15:20 -080043 SetStreams(streams);
Steve Anton60776752018-01-10 11:51:34 -080044 SetMediaChannel(media_channel);
deadbeef70ab1a12015-09-28 16:53:55 -070045 Reconfigure();
46}
47
48AudioRtpReceiver::~AudioRtpReceiver() {
49 track_->GetSource()->UnregisterAudioObserver(this);
50 track_->UnregisterObserver(this);
51 Stop();
52}
53
54void AudioRtpReceiver::OnChanged() {
55 if (cached_track_enabled_ != track_->enabled()) {
56 cached_track_enabled_ = track_->enabled();
57 Reconfigure();
58 }
59}
60
Steve Anton60776752018-01-10 11:51:34 -080061bool AudioRtpReceiver::SetOutputVolume(double volume) {
62 RTC_DCHECK_GE(volume, 0.0);
63 RTC_DCHECK_LE(volume, 10.0);
64 RTC_DCHECK(media_channel_);
65 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
66 return media_channel_->SetOutputVolume(ssrc_, volume);
67 });
68}
69
deadbeef70ab1a12015-09-28 16:53:55 -070070void AudioRtpReceiver::OnSetVolume(double volume) {
kwibergee89e782017-08-09 17:22:01 -070071 RTC_DCHECK_GE(volume, 0);
72 RTC_DCHECK_LE(volume, 10);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070073 cached_volume_ = volume;
Steve Anton60776752018-01-10 11:51:34 -080074 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010075 RTC_LOG(LS_ERROR)
76 << "AudioRtpReceiver::OnSetVolume: No audio channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070077 return;
78 }
deadbeef70ab1a12015-09-28 16:53:55 -070079 // When the track is disabled, the volume of the source, which is the
80 // corresponding WebRtc Voice Engine channel will be 0. So we do not allow
81 // setting the volume to the source when the track is disabled.
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070082 if (!stopped_ && track_->enabled()) {
Steve Anton60776752018-01-10 11:51:34 -080083 if (!SetOutputVolume(cached_volume_)) {
nisseeb4ca4e2017-01-12 02:24:27 -080084 RTC_NOTREACHED();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070085 }
86 }
deadbeef70ab1a12015-09-28 16:53:55 -070087}
88
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -070089RtpParameters AudioRtpReceiver::GetParameters() const {
Steve Anton60776752018-01-10 11:51:34 -080090 if (!media_channel_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070091 return RtpParameters();
92 }
Steve Anton60776752018-01-10 11:51:34 -080093 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
94 return media_channel_->GetRtpReceiveParameters(ssrc_);
95 });
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -070096}
97
98bool AudioRtpReceiver::SetParameters(const RtpParameters& parameters) {
99 TRACE_EVENT0("webrtc", "AudioRtpReceiver::SetParameters");
Steve Anton60776752018-01-10 11:51:34 -0800100 if (!media_channel_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700101 return false;
102 }
Steve Anton60776752018-01-10 11:51:34 -0800103 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
104 return media_channel_->SetRtpReceiveParameters(ssrc_, parameters);
105 });
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700106}
107
deadbeefa601f5c2016-06-06 14:27:39 -0700108void AudioRtpReceiver::Stop() {
109 // TODO(deadbeef): Need to do more here to fully stop receiving packets.
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700110 if (stopped_) {
deadbeefa601f5c2016-06-06 14:27:39 -0700111 return;
112 }
Steve Anton60776752018-01-10 11:51:34 -0800113 if (media_channel_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700114 // Allow that SetOutputVolume fail. This is the normal case when the
115 // underlying media channel has already been deleted.
Steve Anton60776752018-01-10 11:51:34 -0800116 SetOutputVolume(0.0);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700117 }
118 stopped_ = true;
deadbeefa601f5c2016-06-06 14:27:39 -0700119}
120
Steve Antonef65ef12018-01-10 17:15:20 -0800121void AudioRtpReceiver::SetStreams(
122 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
123 // Remove remote track from any streams that are going away.
124 for (auto existing_stream : streams_) {
125 bool removed = true;
126 for (auto stream : streams) {
127 if (existing_stream->label() == stream->label()) {
128 RTC_DCHECK_EQ(existing_stream.get(), stream.get());
129 removed = false;
130 break;
131 }
132 }
133 if (removed) {
134 existing_stream->RemoveTrack(track_);
135 }
136 }
137 // Add remote track to any streams that are new.
138 for (auto stream : streams) {
139 bool added = true;
140 for (auto existing_stream : streams_) {
141 if (stream->label() == existing_stream->label()) {
142 RTC_DCHECK_EQ(stream.get(), existing_stream.get());
143 added = false;
144 break;
145 }
146 }
147 if (added) {
148 stream->AddTrack(track_);
149 }
150 }
151 streams_ = streams;
152}
153
hbos8d609f62017-04-10 07:39:05 -0700154std::vector<RtpSource> AudioRtpReceiver::GetSources() const {
Steve Anton60776752018-01-10 11:51:34 -0800155 return worker_thread_->Invoke<std::vector<RtpSource>>(
156 RTC_FROM_HERE, [&] { return media_channel_->GetSources(ssrc_); });
hbos8d609f62017-04-10 07:39:05 -0700157}
158
deadbeef70ab1a12015-09-28 16:53:55 -0700159void AudioRtpReceiver::Reconfigure() {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700160 RTC_DCHECK(!stopped_);
Steve Anton60776752018-01-10 11:51:34 -0800161 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100162 RTC_LOG(LS_ERROR)
163 << "AudioRtpReceiver::Reconfigure: No audio channel exists.";
deadbeef70ab1a12015-09-28 16:53:55 -0700164 return;
165 }
Steve Anton60776752018-01-10 11:51:34 -0800166 if (!SetOutputVolume(track_->enabled() ? cached_volume_ : 0)) {
nisseeb4ca4e2017-01-12 02:24:27 -0800167 RTC_NOTREACHED();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700168 }
deadbeef70ab1a12015-09-28 16:53:55 -0700169}
170
zhihuang184a3fd2016-06-14 11:47:14 -0700171void AudioRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
172 observer_ = observer;
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700173 // Deliver any notifications the observer may have missed by being set late.
zhihuangc4adabf2016-12-07 10:36:40 -0800174 if (received_first_packet_ && observer_) {
zhihuang184a3fd2016-06-14 11:47:14 -0700175 observer_->OnFirstPacketReceived(media_type());
176 }
177}
178
Steve Anton60776752018-01-10 11:51:34 -0800179void AudioRtpReceiver::SetMediaChannel(
180 cricket::VoiceMediaChannel* media_channel) {
181 media_channel_ = media_channel;
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700182}
183
Steve Anton60776752018-01-10 11:51:34 -0800184void AudioRtpReceiver::NotifyFirstPacketReceived() {
zhihuang184a3fd2016-06-14 11:47:14 -0700185 if (observer_) {
186 observer_->OnFirstPacketReceived(media_type());
187 }
188 received_first_packet_ = true;
189}
190
Henrik Boström9e6fd2b2017-11-21 13:41:51 +0100191VideoRtpReceiver::VideoRtpReceiver(
Steve Anton60776752018-01-10 11:51:34 -0800192 rtc::Thread* worker_thread,
Steve Antonef65ef12018-01-10 17:15:20 -0800193 const std::string& receiver_id,
194 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams,
Henrik Boström9e6fd2b2017-11-21 13:41:51 +0100195 uint32_t ssrc,
Steve Anton60776752018-01-10 11:51:34 -0800196 cricket::VideoMediaChannel* media_channel)
197 : worker_thread_(worker_thread),
Steve Antonef65ef12018-01-10 17:15:20 -0800198 id_(receiver_id),
perkjf0dcfe22016-03-10 18:32:00 +0100199 ssrc_(ssrc),
perkjf0dcfe22016-03-10 18:32:00 +0100200 source_(new RefCountedObject<VideoTrackSource>(&broadcaster_,
perkjf0dcfe22016-03-10 18:32:00 +0100201 true /* remote */)),
202 track_(VideoTrackProxy::Create(
203 rtc::Thread::Current(),
nisse5b68ab52016-04-07 07:45:54 -0700204 worker_thread,
205 VideoTrack::Create(
Steve Antonef65ef12018-01-10 17:15:20 -0800206 receiver_id,
nisse5b68ab52016-04-07 07:45:54 -0700207 VideoTrackSourceProxy::Create(rtc::Thread::Current(),
208 worker_thread,
perkj773be362017-07-31 23:22:01 -0700209 source_),
Steve Antonef65ef12018-01-10 17:15:20 -0800210 worker_thread))) {
Steve Anton60776752018-01-10 11:51:34 -0800211 RTC_DCHECK(worker_thread_);
Steve Antonef65ef12018-01-10 17:15:20 -0800212 SetStreams(streams);
perkjf0dcfe22016-03-10 18:32:00 +0100213 source_->SetState(MediaSourceInterface::kLive);
Steve Anton60776752018-01-10 11:51:34 -0800214 SetMediaChannel(media_channel);
deadbeef70ab1a12015-09-28 16:53:55 -0700215}
216
217VideoRtpReceiver::~VideoRtpReceiver() {
218 // Since cricket::VideoRenderer is not reference counted,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700219 // we need to remove it from the channel before we are deleted.
deadbeef70ab1a12015-09-28 16:53:55 -0700220 Stop();
221}
222
Steve Anton60776752018-01-10 11:51:34 -0800223bool VideoRtpReceiver::SetSink(rtc::VideoSinkInterface<VideoFrame>* sink) {
224 RTC_DCHECK(media_channel_);
225 return worker_thread_->Invoke<bool>(
226 RTC_FROM_HERE, [&] { return media_channel_->SetSink(ssrc_, sink); });
227}
228
deadbeefa601f5c2016-06-06 14:27:39 -0700229RtpParameters VideoRtpReceiver::GetParameters() const {
Steve Anton60776752018-01-10 11:51:34 -0800230 if (!media_channel_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700231 return RtpParameters();
232 }
Steve Anton60776752018-01-10 11:51:34 -0800233 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
234 return media_channel_->GetRtpReceiveParameters(ssrc_);
235 });
deadbeefa601f5c2016-06-06 14:27:39 -0700236}
237
238bool VideoRtpReceiver::SetParameters(const RtpParameters& parameters) {
239 TRACE_EVENT0("webrtc", "VideoRtpReceiver::SetParameters");
Steve Anton60776752018-01-10 11:51:34 -0800240 if (!media_channel_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700241 return false;
242 }
Steve Anton60776752018-01-10 11:51:34 -0800243 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
244 return media_channel_->SetRtpReceiveParameters(ssrc_, parameters);
245 });
deadbeefa601f5c2016-06-06 14:27:39 -0700246}
247
deadbeef70ab1a12015-09-28 16:53:55 -0700248void VideoRtpReceiver::Stop() {
249 // TODO(deadbeef): Need to do more here to fully stop receiving packets.
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700250 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700251 return;
252 }
perkjf0dcfe22016-03-10 18:32:00 +0100253 source_->SetState(MediaSourceInterface::kEnded);
254 source_->OnSourceDestroyed();
Steve Anton60776752018-01-10 11:51:34 -0800255 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100256 RTC_LOG(LS_WARNING) << "VideoRtpReceiver::Stop: No video channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700257 } else {
258 // Allow that SetSink fail. This is the normal case when the underlying
259 // media channel has already been deleted.
Steve Anton60776752018-01-10 11:51:34 -0800260 SetSink(nullptr);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700261 }
262 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700263}
264
Steve Antonef65ef12018-01-10 17:15:20 -0800265void VideoRtpReceiver::SetStreams(
266 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
267 // Remove remote track from any streams that are going away.
268 for (auto existing_stream : streams_) {
269 bool removed = true;
270 for (auto stream : streams) {
271 if (existing_stream->label() == stream->label()) {
272 RTC_DCHECK_EQ(existing_stream.get(), stream.get());
273 removed = false;
274 break;
275 }
276 }
277 if (removed) {
278 existing_stream->RemoveTrack(track_);
279 }
280 }
281 // Add remote track to any streams that are new.
282 for (auto stream : streams) {
283 bool added = true;
284 for (auto existing_stream : streams_) {
285 if (stream->label() == existing_stream->label()) {
286 RTC_DCHECK_EQ(stream.get(), existing_stream.get());
287 added = false;
288 break;
289 }
290 }
291 if (added) {
292 stream->AddTrack(track_);
293 }
294 }
295 streams_ = streams;
296}
297
zhihuang184a3fd2016-06-14 11:47:14 -0700298void VideoRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
299 observer_ = observer;
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700300 // Deliver any notifications the observer may have missed by being set late.
zhihuangc4adabf2016-12-07 10:36:40 -0800301 if (received_first_packet_ && observer_) {
zhihuang184a3fd2016-06-14 11:47:14 -0700302 observer_->OnFirstPacketReceived(media_type());
303 }
304}
305
Steve Anton60776752018-01-10 11:51:34 -0800306void VideoRtpReceiver::SetMediaChannel(
307 cricket::VideoMediaChannel* media_channel) {
308 if (media_channel_) {
309 SetSink(nullptr);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700310 }
Steve Anton60776752018-01-10 11:51:34 -0800311 media_channel_ = media_channel;
312 if (media_channel_) {
313 if (!SetSink(&broadcaster_)) {
nisseeb4ca4e2017-01-12 02:24:27 -0800314 RTC_NOTREACHED();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700315 }
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700316 }
317}
318
Steve Anton60776752018-01-10 11:51:34 -0800319void VideoRtpReceiver::NotifyFirstPacketReceived() {
zhihuang184a3fd2016-06-14 11:47:14 -0700320 if (observer_) {
321 observer_->OnFirstPacketReceived(media_type());
322 }
323 received_first_packet_ = true;
324}
325
deadbeef70ab1a12015-09-28 16:53:55 -0700326} // namespace webrtc