blob: e318c17e144d594dab083ab79729ecff71c38a46 [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
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
Henrik Boström9e6fd2b2017-11-21 13:41:51 +010035AudioRtpReceiver::AudioRtpReceiver(
Steve Anton60776752018-01-10 11:51:34 -080036 rtc::Thread* worker_thread,
Steve Anton9158ef62017-11-27 13:01:52 -080037 const std::string& receiver_id,
Steve Antonef65ef12018-01-10 17:15:20 -080038 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams,
Henrik Boström9e6fd2b2017-11-21 13:41:51 +010039 uint32_t ssrc,
Steve Anton60776752018-01-10 11:51:34 -080040 cricket::VoiceMediaChannel* media_channel)
41 : worker_thread_(worker_thread),
42 id_(receiver_id),
deadbeef70ab1a12015-09-28 16:53:55 -070043 ssrc_(ssrc),
perkjd61bf802016-03-24 03:16:19 -070044 track_(AudioTrackProxy::Create(
45 rtc::Thread::Current(),
Steve Anton60776752018-01-10 11:51:34 -080046 AudioTrack::Create(
47 receiver_id,
48 RemoteAudioSource::Create(worker_thread, media_channel, ssrc)))),
Harald Alvestrandc72af932018-01-11 17:18:19 +010049 cached_track_enabled_(track_->enabled()),
50 attachment_id_(GenerateUniqueId()) {
Steve Anton60776752018-01-10 11:51:34 -080051 RTC_DCHECK(worker_thread_);
tommi6eca7e32015-12-15 04:27:11 -080052 RTC_DCHECK(track_->GetSource()->remote());
deadbeef70ab1a12015-09-28 16:53:55 -070053 track_->RegisterObserver(this);
54 track_->GetSource()->RegisterAudioObserver(this);
Steve Antonef65ef12018-01-10 17:15:20 -080055 SetStreams(streams);
Steve Anton60776752018-01-10 11:51:34 -080056 SetMediaChannel(media_channel);
deadbeef70ab1a12015-09-28 16:53:55 -070057 Reconfigure();
58}
59
60AudioRtpReceiver::~AudioRtpReceiver() {
61 track_->GetSource()->UnregisterAudioObserver(this);
62 track_->UnregisterObserver(this);
63 Stop();
64}
65
66void AudioRtpReceiver::OnChanged() {
67 if (cached_track_enabled_ != track_->enabled()) {
68 cached_track_enabled_ = track_->enabled();
69 Reconfigure();
70 }
71}
72
Steve Anton60776752018-01-10 11:51:34 -080073bool AudioRtpReceiver::SetOutputVolume(double volume) {
74 RTC_DCHECK_GE(volume, 0.0);
75 RTC_DCHECK_LE(volume, 10.0);
76 RTC_DCHECK(media_channel_);
77 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
78 return media_channel_->SetOutputVolume(ssrc_, volume);
79 });
80}
81
deadbeef70ab1a12015-09-28 16:53:55 -070082void AudioRtpReceiver::OnSetVolume(double volume) {
kwibergee89e782017-08-09 17:22:01 -070083 RTC_DCHECK_GE(volume, 0);
84 RTC_DCHECK_LE(volume, 10);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070085 cached_volume_ = volume;
Steve Anton60776752018-01-10 11:51:34 -080086 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010087 RTC_LOG(LS_ERROR)
88 << "AudioRtpReceiver::OnSetVolume: No audio channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070089 return;
90 }
deadbeef70ab1a12015-09-28 16:53:55 -070091 // When the track is disabled, the volume of the source, which is the
92 // corresponding WebRtc Voice Engine channel will be 0. So we do not allow
93 // setting the volume to the source when the track is disabled.
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070094 if (!stopped_ && track_->enabled()) {
Steve Anton60776752018-01-10 11:51:34 -080095 if (!SetOutputVolume(cached_volume_)) {
nisseeb4ca4e2017-01-12 02:24:27 -080096 RTC_NOTREACHED();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -070097 }
98 }
deadbeef70ab1a12015-09-28 16:53:55 -070099}
100
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700101RtpParameters AudioRtpReceiver::GetParameters() const {
Steve Anton60776752018-01-10 11:51:34 -0800102 if (!media_channel_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700103 return RtpParameters();
104 }
Steve Anton60776752018-01-10 11:51:34 -0800105 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
106 return media_channel_->GetRtpReceiveParameters(ssrc_);
107 });
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700108}
109
110bool AudioRtpReceiver::SetParameters(const RtpParameters& parameters) {
111 TRACE_EVENT0("webrtc", "AudioRtpReceiver::SetParameters");
Steve Anton60776752018-01-10 11:51:34 -0800112 if (!media_channel_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700113 return false;
114 }
Steve Anton60776752018-01-10 11:51:34 -0800115 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
116 return media_channel_->SetRtpReceiveParameters(ssrc_, parameters);
117 });
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700118}
119
deadbeefa601f5c2016-06-06 14:27:39 -0700120void AudioRtpReceiver::Stop() {
121 // TODO(deadbeef): Need to do more here to fully stop receiving packets.
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700122 if (stopped_) {
deadbeefa601f5c2016-06-06 14:27:39 -0700123 return;
124 }
Steve Anton60776752018-01-10 11:51:34 -0800125 if (media_channel_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700126 // Allow that SetOutputVolume fail. This is the normal case when the
127 // underlying media channel has already been deleted.
Steve Anton60776752018-01-10 11:51:34 -0800128 SetOutputVolume(0.0);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700129 }
130 stopped_ = true;
deadbeefa601f5c2016-06-06 14:27:39 -0700131}
132
Steve Antonef65ef12018-01-10 17:15:20 -0800133void AudioRtpReceiver::SetStreams(
134 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
135 // Remove remote track from any streams that are going away.
136 for (auto existing_stream : streams_) {
137 bool removed = true;
138 for (auto stream : streams) {
139 if (existing_stream->label() == stream->label()) {
140 RTC_DCHECK_EQ(existing_stream.get(), stream.get());
141 removed = false;
142 break;
143 }
144 }
145 if (removed) {
146 existing_stream->RemoveTrack(track_);
147 }
148 }
149 // Add remote track to any streams that are new.
150 for (auto stream : streams) {
151 bool added = true;
152 for (auto existing_stream : streams_) {
153 if (stream->label() == existing_stream->label()) {
154 RTC_DCHECK_EQ(stream.get(), existing_stream.get());
155 added = false;
156 break;
157 }
158 }
159 if (added) {
160 stream->AddTrack(track_);
161 }
162 }
163 streams_ = streams;
164}
165
hbos8d609f62017-04-10 07:39:05 -0700166std::vector<RtpSource> AudioRtpReceiver::GetSources() const {
Steve Anton60776752018-01-10 11:51:34 -0800167 return worker_thread_->Invoke<std::vector<RtpSource>>(
168 RTC_FROM_HERE, [&] { return media_channel_->GetSources(ssrc_); });
hbos8d609f62017-04-10 07:39:05 -0700169}
170
deadbeef70ab1a12015-09-28 16:53:55 -0700171void AudioRtpReceiver::Reconfigure() {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700172 RTC_DCHECK(!stopped_);
Steve Anton60776752018-01-10 11:51:34 -0800173 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100174 RTC_LOG(LS_ERROR)
175 << "AudioRtpReceiver::Reconfigure: No audio channel exists.";
deadbeef70ab1a12015-09-28 16:53:55 -0700176 return;
177 }
Steve Anton60776752018-01-10 11:51:34 -0800178 if (!SetOutputVolume(track_->enabled() ? cached_volume_ : 0)) {
nisseeb4ca4e2017-01-12 02:24:27 -0800179 RTC_NOTREACHED();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700180 }
deadbeef70ab1a12015-09-28 16:53:55 -0700181}
182
zhihuang184a3fd2016-06-14 11:47:14 -0700183void AudioRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
184 observer_ = observer;
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700185 // Deliver any notifications the observer may have missed by being set late.
zhihuangc4adabf2016-12-07 10:36:40 -0800186 if (received_first_packet_ && observer_) {
zhihuang184a3fd2016-06-14 11:47:14 -0700187 observer_->OnFirstPacketReceived(media_type());
188 }
189}
190
Steve Anton60776752018-01-10 11:51:34 -0800191void AudioRtpReceiver::SetMediaChannel(
192 cricket::VoiceMediaChannel* media_channel) {
193 media_channel_ = media_channel;
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700194}
195
Steve Anton60776752018-01-10 11:51:34 -0800196void AudioRtpReceiver::NotifyFirstPacketReceived() {
zhihuang184a3fd2016-06-14 11:47:14 -0700197 if (observer_) {
198 observer_->OnFirstPacketReceived(media_type());
199 }
200 received_first_packet_ = true;
201}
202
Henrik Boström9e6fd2b2017-11-21 13:41:51 +0100203VideoRtpReceiver::VideoRtpReceiver(
Steve Anton60776752018-01-10 11:51:34 -0800204 rtc::Thread* worker_thread,
Steve Antonef65ef12018-01-10 17:15:20 -0800205 const std::string& receiver_id,
206 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams,
Henrik Boström9e6fd2b2017-11-21 13:41:51 +0100207 uint32_t ssrc,
Steve Anton60776752018-01-10 11:51:34 -0800208 cricket::VideoMediaChannel* media_channel)
209 : worker_thread_(worker_thread),
Steve Antonef65ef12018-01-10 17:15:20 -0800210 id_(receiver_id),
perkjf0dcfe22016-03-10 18:32:00 +0100211 ssrc_(ssrc),
perkjf0dcfe22016-03-10 18:32:00 +0100212 source_(new RefCountedObject<VideoTrackSource>(&broadcaster_,
perkjf0dcfe22016-03-10 18:32:00 +0100213 true /* remote */)),
214 track_(VideoTrackProxy::Create(
215 rtc::Thread::Current(),
nisse5b68ab52016-04-07 07:45:54 -0700216 worker_thread,
217 VideoTrack::Create(
Steve Antonef65ef12018-01-10 17:15:20 -0800218 receiver_id,
nisse5b68ab52016-04-07 07:45:54 -0700219 VideoTrackSourceProxy::Create(rtc::Thread::Current(),
220 worker_thread,
perkj773be362017-07-31 23:22:01 -0700221 source_),
Harald Alvestrandc72af932018-01-11 17:18:19 +0100222 worker_thread))),
223 attachment_id_(GenerateUniqueId()) {
Steve Anton60776752018-01-10 11:51:34 -0800224 RTC_DCHECK(worker_thread_);
Steve Antonef65ef12018-01-10 17:15:20 -0800225 SetStreams(streams);
perkjf0dcfe22016-03-10 18:32:00 +0100226 source_->SetState(MediaSourceInterface::kLive);
Steve Anton60776752018-01-10 11:51:34 -0800227 SetMediaChannel(media_channel);
deadbeef70ab1a12015-09-28 16:53:55 -0700228}
229
230VideoRtpReceiver::~VideoRtpReceiver() {
231 // Since cricket::VideoRenderer is not reference counted,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700232 // we need to remove it from the channel before we are deleted.
deadbeef70ab1a12015-09-28 16:53:55 -0700233 Stop();
234}
235
Steve Anton60776752018-01-10 11:51:34 -0800236bool VideoRtpReceiver::SetSink(rtc::VideoSinkInterface<VideoFrame>* sink) {
237 RTC_DCHECK(media_channel_);
238 return worker_thread_->Invoke<bool>(
239 RTC_FROM_HERE, [&] { return media_channel_->SetSink(ssrc_, sink); });
240}
241
deadbeefa601f5c2016-06-06 14:27:39 -0700242RtpParameters VideoRtpReceiver::GetParameters() const {
Steve Anton60776752018-01-10 11:51:34 -0800243 if (!media_channel_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700244 return RtpParameters();
245 }
Steve Anton60776752018-01-10 11:51:34 -0800246 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
247 return media_channel_->GetRtpReceiveParameters(ssrc_);
248 });
deadbeefa601f5c2016-06-06 14:27:39 -0700249}
250
251bool VideoRtpReceiver::SetParameters(const RtpParameters& parameters) {
252 TRACE_EVENT0("webrtc", "VideoRtpReceiver::SetParameters");
Steve Anton60776752018-01-10 11:51:34 -0800253 if (!media_channel_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700254 return false;
255 }
Steve Anton60776752018-01-10 11:51:34 -0800256 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
257 return media_channel_->SetRtpReceiveParameters(ssrc_, parameters);
258 });
deadbeefa601f5c2016-06-06 14:27:39 -0700259}
260
deadbeef70ab1a12015-09-28 16:53:55 -0700261void VideoRtpReceiver::Stop() {
262 // TODO(deadbeef): Need to do more here to fully stop receiving packets.
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700263 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700264 return;
265 }
perkjf0dcfe22016-03-10 18:32:00 +0100266 source_->SetState(MediaSourceInterface::kEnded);
267 source_->OnSourceDestroyed();
Steve Anton60776752018-01-10 11:51:34 -0800268 if (!media_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100269 RTC_LOG(LS_WARNING) << "VideoRtpReceiver::Stop: No video channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700270 } else {
271 // Allow that SetSink fail. This is the normal case when the underlying
272 // media channel has already been deleted.
Steve Anton60776752018-01-10 11:51:34 -0800273 SetSink(nullptr);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700274 }
275 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700276}
277
Steve Antonef65ef12018-01-10 17:15:20 -0800278void VideoRtpReceiver::SetStreams(
279 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
280 // Remove remote track from any streams that are going away.
281 for (auto existing_stream : streams_) {
282 bool removed = true;
283 for (auto stream : streams) {
284 if (existing_stream->label() == stream->label()) {
285 RTC_DCHECK_EQ(existing_stream.get(), stream.get());
286 removed = false;
287 break;
288 }
289 }
290 if (removed) {
291 existing_stream->RemoveTrack(track_);
292 }
293 }
294 // Add remote track to any streams that are new.
295 for (auto stream : streams) {
296 bool added = true;
297 for (auto existing_stream : streams_) {
298 if (stream->label() == existing_stream->label()) {
299 RTC_DCHECK_EQ(stream.get(), existing_stream.get());
300 added = false;
301 break;
302 }
303 }
304 if (added) {
305 stream->AddTrack(track_);
306 }
307 }
308 streams_ = streams;
309}
310
zhihuang184a3fd2016-06-14 11:47:14 -0700311void VideoRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
312 observer_ = observer;
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700313 // Deliver any notifications the observer may have missed by being set late.
zhihuangc4adabf2016-12-07 10:36:40 -0800314 if (received_first_packet_ && observer_) {
zhihuang184a3fd2016-06-14 11:47:14 -0700315 observer_->OnFirstPacketReceived(media_type());
316 }
317}
318
Steve Anton60776752018-01-10 11:51:34 -0800319void VideoRtpReceiver::SetMediaChannel(
320 cricket::VideoMediaChannel* media_channel) {
321 if (media_channel_) {
322 SetSink(nullptr);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700323 }
Steve Anton60776752018-01-10 11:51:34 -0800324 media_channel_ = media_channel;
325 if (media_channel_) {
326 if (!SetSink(&broadcaster_)) {
nisseeb4ca4e2017-01-12 02:24:27 -0800327 RTC_NOTREACHED();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700328 }
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700329 }
330}
331
Steve Anton60776752018-01-10 11:51:34 -0800332void VideoRtpReceiver::NotifyFirstPacketReceived() {
zhihuang184a3fd2016-06-14 11:47:14 -0700333 if (observer_) {
334 observer_->OnFirstPacketReceived(media_type());
335 }
336 received_first_packet_ = true;
337}
338
deadbeef70ab1a12015-09-28 16:53:55 -0700339} // namespace webrtc