blob: be1bd4b067f3a10033a97a0e02581ccda306f5bb [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
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <stddef.h>
Henrik Boström9e6fd2b2017-11-21 13:41:51 +010014#include <utility>
Steve Anton36b29d12017-10-30 09:57:42 -070015#include <vector>
16
Henrik Boström199e27b2018-07-04 20:51:53 +020017#include "api/mediastreamproxy.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "api/mediastreamtrackproxy.h"
19#include "api/videosourceproxy.h"
20#include "pc/audiotrack.h"
Henrik Boström199e27b2018-07-04 20:51:53 +020021#include "pc/mediastream.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "pc/videotrack.h"
Yves Gerey3e707812018-11-28 16:47:49 +010023#include "rtc_base/checks.h"
24#include "rtc_base/location.h"
25#include "rtc_base/logging.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "rtc_base/trace_event.h"
deadbeef70ab1a12015-09-28 16:53:55 -070027
28namespace webrtc {
29
Harald Alvestrandc72af932018-01-11 17:18:19 +010030namespace {
31
32// This function is only expected to be called on the signalling thread.
33int GenerateUniqueId() {
34 static int g_unique_id = 0;
35
36 return ++g_unique_id;
37}
38
Henrik Boström199e27b2018-07-04 20:51:53 +020039std::vector<rtc::scoped_refptr<MediaStreamInterface>> CreateStreamsFromIds(
40 std::vector<std::string> stream_ids) {
41 std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams(
42 stream_ids.size());
43 for (size_t i = 0; i < stream_ids.size(); ++i) {
44 streams[i] = MediaStreamProxy::Create(
45 rtc::Thread::Current(), MediaStream::Create(std::move(stream_ids[i])));
46 }
47 return streams;
48}
49
Benjamin Wright84583f62018-10-04 14:22:34 -070050// Attempt to attach the frame decryptor to the current media channel on the
51// correct worker thread only if both the media channel exists and a ssrc has
52// been allocated to the stream.
53void MaybeAttachFrameDecryptorToMediaChannel(
54 const absl::optional<uint32_t>& ssrc,
Benjamin Wrightbfd412e2018-09-10 14:06:02 -070055 rtc::Thread* worker_thread,
Benjamin Wright84583f62018-10-04 14:22:34 -070056 rtc::scoped_refptr<webrtc::FrameDecryptorInterface> frame_decryptor,
Benjamin Wrightc462a6e2018-10-26 13:16:16 -070057 cricket::MediaChannel* media_channel,
58 bool stopped) {
59 if (media_channel && frame_decryptor && ssrc.has_value() && !stopped) {
Benjamin Wright6cc9cca2018-10-09 17:29:54 -070060 worker_thread->Invoke<void>(RTC_FROM_HERE, [&] {
Benjamin Wright84583f62018-10-04 14:22:34 -070061 media_channel->SetFrameDecryptor(*ssrc, frame_decryptor);
Benjamin Wrightbfd412e2018-09-10 14:06:02 -070062 });
63 }
64}
65
Harald Alvestrandc72af932018-01-11 17:18:19 +010066} // namespace
67
Henrik Boström199e27b2018-07-04 20:51:53 +020068AudioRtpReceiver::AudioRtpReceiver(rtc::Thread* worker_thread,
69 std::string receiver_id,
70 std::vector<std::string> stream_ids)
71 : AudioRtpReceiver(worker_thread,
72 receiver_id,
73 CreateStreamsFromIds(std::move(stream_ids))) {}
74
Henrik Boström9e6fd2b2017-11-21 13:41:51 +010075AudioRtpReceiver::AudioRtpReceiver(
Steve Anton60776752018-01-10 11:51:34 -080076 rtc::Thread* worker_thread,
Steve Anton9158ef62017-11-27 13:01:52 -080077 const std::string& receiver_id,
Steve Antond3679212018-01-17 17:41:02 -080078 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams)
Steve Anton60776752018-01-10 11:51:34 -080079 : worker_thread_(worker_thread),
80 id_(receiver_id),
Steve Antond3679212018-01-17 17:41:02 -080081 source_(new rtc::RefCountedObject<RemoteAudioSource>(worker_thread)),
82 track_(AudioTrackProxy::Create(rtc::Thread::Current(),
83 AudioTrack::Create(receiver_id, source_))),
Harald Alvestrandc72af932018-01-11 17:18:19 +010084 cached_track_enabled_(track_->enabled()),
85 attachment_id_(GenerateUniqueId()) {
Steve Anton60776752018-01-10 11:51:34 -080086 RTC_DCHECK(worker_thread_);
tommi6eca7e32015-12-15 04:27:11 -080087 RTC_DCHECK(track_->GetSource()->remote());
deadbeef70ab1a12015-09-28 16:53:55 -070088 track_->RegisterObserver(this);
89 track_->GetSource()->RegisterAudioObserver(this);
Steve Antonef65ef12018-01-10 17:15:20 -080090 SetStreams(streams);
deadbeef70ab1a12015-09-28 16:53:55 -070091}
92
93AudioRtpReceiver::~AudioRtpReceiver() {
94 track_->GetSource()->UnregisterAudioObserver(this);
95 track_->UnregisterObserver(this);
96 Stop();
97}
98
99void AudioRtpReceiver::OnChanged() {
100 if (cached_track_enabled_ != track_->enabled()) {
101 cached_track_enabled_ = track_->enabled();
102 Reconfigure();
103 }
104}
105
Steve Anton60776752018-01-10 11:51:34 -0800106bool AudioRtpReceiver::SetOutputVolume(double volume) {
107 RTC_DCHECK_GE(volume, 0.0);
108 RTC_DCHECK_LE(volume, 10.0);
109 RTC_DCHECK(media_channel_);
Steve Antond3679212018-01-17 17:41:02 -0800110 RTC_DCHECK(ssrc_);
Steve Anton60776752018-01-10 11:51:34 -0800111 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
Steve Antond3679212018-01-17 17:41:02 -0800112 return media_channel_->SetOutputVolume(*ssrc_, volume);
Steve Anton60776752018-01-10 11:51:34 -0800113 });
114}
115
deadbeef70ab1a12015-09-28 16:53:55 -0700116void AudioRtpReceiver::OnSetVolume(double volume) {
kwibergee89e782017-08-09 17:22:01 -0700117 RTC_DCHECK_GE(volume, 0);
118 RTC_DCHECK_LE(volume, 10);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700119 cached_volume_ = volume;
Steve Antond3679212018-01-17 17:41:02 -0800120 if (!media_channel_ || !ssrc_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100121 RTC_LOG(LS_ERROR)
122 << "AudioRtpReceiver::OnSetVolume: No audio channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700123 return;
124 }
deadbeef70ab1a12015-09-28 16:53:55 -0700125 // When the track is disabled, the volume of the source, which is the
126 // corresponding WebRtc Voice Engine channel will be 0. So we do not allow
127 // setting the volume to the source when the track is disabled.
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700128 if (!stopped_ && track_->enabled()) {
Steve Anton60776752018-01-10 11:51:34 -0800129 if (!SetOutputVolume(cached_volume_)) {
nisseeb4ca4e2017-01-12 02:24:27 -0800130 RTC_NOTREACHED();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700131 }
132 }
deadbeef70ab1a12015-09-28 16:53:55 -0700133}
134
Henrik Boström199e27b2018-07-04 20:51:53 +0200135std::vector<std::string> AudioRtpReceiver::stream_ids() const {
136 std::vector<std::string> stream_ids(streams_.size());
137 for (size_t i = 0; i < streams_.size(); ++i)
138 stream_ids[i] = streams_[i]->id();
139 return stream_ids;
140}
141
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700142RtpParameters AudioRtpReceiver::GetParameters() const {
Steve Antond3679212018-01-17 17:41:02 -0800143 if (!media_channel_ || !ssrc_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700144 return RtpParameters();
145 }
Steve Anton60776752018-01-10 11:51:34 -0800146 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
Steve Antond3679212018-01-17 17:41:02 -0800147 return media_channel_->GetRtpReceiveParameters(*ssrc_);
Steve Anton60776752018-01-10 11:51:34 -0800148 });
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700149}
150
151bool AudioRtpReceiver::SetParameters(const RtpParameters& parameters) {
152 TRACE_EVENT0("webrtc", "AudioRtpReceiver::SetParameters");
Steve Antond3679212018-01-17 17:41:02 -0800153 if (!media_channel_ || !ssrc_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700154 return false;
155 }
Steve Anton60776752018-01-10 11:51:34 -0800156 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
Steve Antond3679212018-01-17 17:41:02 -0800157 return media_channel_->SetRtpReceiveParameters(*ssrc_, parameters);
Steve Anton60776752018-01-10 11:51:34 -0800158 });
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700159}
160
Benjamin Wrightd81ac952018-08-29 17:02:10 -0700161void AudioRtpReceiver::SetFrameDecryptor(
162 rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
163 frame_decryptor_ = std::move(frame_decryptor);
Benjamin Wright6cc9cca2018-10-09 17:29:54 -0700164 // Special Case: Set the frame decryptor to any value on any existing channel.
Benjamin Wrightc462a6e2018-10-26 13:16:16 -0700165 if (media_channel_ && ssrc_.has_value() && !stopped_) {
Benjamin Wright6cc9cca2018-10-09 17:29:54 -0700166 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
167 media_channel_->SetFrameDecryptor(*ssrc_, frame_decryptor_);
168 });
169 }
Benjamin Wrightd81ac952018-08-29 17:02:10 -0700170}
171
172rtc::scoped_refptr<FrameDecryptorInterface>
173AudioRtpReceiver::GetFrameDecryptor() const {
174 return frame_decryptor_;
175}
176
deadbeefa601f5c2016-06-06 14:27:39 -0700177void AudioRtpReceiver::Stop() {
178 // TODO(deadbeef): Need to do more here to fully stop receiving packets.
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700179 if (stopped_) {
deadbeefa601f5c2016-06-06 14:27:39 -0700180 return;
181 }
Steve Antond3679212018-01-17 17:41:02 -0800182 if (media_channel_ && ssrc_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700183 // Allow that SetOutputVolume fail. This is the normal case when the
184 // underlying media channel has already been deleted.
Steve Anton60776752018-01-10 11:51:34 -0800185 SetOutputVolume(0.0);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700186 }
187 stopped_ = true;
deadbeefa601f5c2016-06-06 14:27:39 -0700188}
189
Steve Antond3679212018-01-17 17:41:02 -0800190void AudioRtpReceiver::SetupMediaChannel(uint32_t ssrc) {
191 if (!media_channel_) {
192 RTC_LOG(LS_ERROR)
193 << "AudioRtpReceiver::SetupMediaChannel: No audio channel exists.";
194 return;
195 }
196 if (ssrc_ == ssrc) {
197 return;
198 }
199 if (ssrc_) {
200 source_->Stop(media_channel_, *ssrc_);
201 }
202 ssrc_ = ssrc;
203 source_->Start(media_channel_, *ssrc_);
204 Reconfigure();
205}
206
Henrik Boström199e27b2018-07-04 20:51:53 +0200207void AudioRtpReceiver::set_stream_ids(std::vector<std::string> stream_ids) {
208 SetStreams(CreateStreamsFromIds(std::move(stream_ids)));
209}
210
Steve Antonef65ef12018-01-10 17:15:20 -0800211void AudioRtpReceiver::SetStreams(
212 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
213 // Remove remote track from any streams that are going away.
214 for (auto existing_stream : streams_) {
215 bool removed = true;
216 for (auto stream : streams) {
Seth Hampson13b8bad2018-03-13 16:05:28 -0700217 if (existing_stream->id() == stream->id()) {
Steve Antonef65ef12018-01-10 17:15:20 -0800218 RTC_DCHECK_EQ(existing_stream.get(), stream.get());
219 removed = false;
220 break;
221 }
222 }
223 if (removed) {
224 existing_stream->RemoveTrack(track_);
225 }
226 }
227 // Add remote track to any streams that are new.
228 for (auto stream : streams) {
229 bool added = true;
230 for (auto existing_stream : streams_) {
Seth Hampson13b8bad2018-03-13 16:05:28 -0700231 if (stream->id() == existing_stream->id()) {
Steve Antonef65ef12018-01-10 17:15:20 -0800232 RTC_DCHECK_EQ(stream.get(), existing_stream.get());
233 added = false;
234 break;
235 }
236 }
237 if (added) {
238 stream->AddTrack(track_);
239 }
240 }
241 streams_ = streams;
242}
243
hbos8d609f62017-04-10 07:39:05 -0700244std::vector<RtpSource> AudioRtpReceiver::GetSources() const {
Steve Antond3679212018-01-17 17:41:02 -0800245 if (!media_channel_ || !ssrc_ || stopped_) {
246 return {};
247 }
Steve Anton60776752018-01-10 11:51:34 -0800248 return worker_thread_->Invoke<std::vector<RtpSource>>(
Steve Antond3679212018-01-17 17:41:02 -0800249 RTC_FROM_HERE, [&] { return media_channel_->GetSources(*ssrc_); });
hbos8d609f62017-04-10 07:39:05 -0700250}
251
deadbeef70ab1a12015-09-28 16:53:55 -0700252void AudioRtpReceiver::Reconfigure() {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700253 RTC_DCHECK(!stopped_);
Steve Antond3679212018-01-17 17:41:02 -0800254 if (!media_channel_ || !ssrc_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100255 RTC_LOG(LS_ERROR)
256 << "AudioRtpReceiver::Reconfigure: No audio channel exists.";
deadbeef70ab1a12015-09-28 16:53:55 -0700257 return;
258 }
Steve Anton60776752018-01-10 11:51:34 -0800259 if (!SetOutputVolume(track_->enabled() ? cached_volume_ : 0)) {
nisseeb4ca4e2017-01-12 02:24:27 -0800260 RTC_NOTREACHED();
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700261 }
Benjamin Wright84583f62018-10-04 14:22:34 -0700262 // Reattach the frame decryptor if we were reconfigured.
Benjamin Wrightc462a6e2018-10-26 13:16:16 -0700263 MaybeAttachFrameDecryptorToMediaChannel(
264 ssrc_, worker_thread_, frame_decryptor_, media_channel_, stopped_);
deadbeef70ab1a12015-09-28 16:53:55 -0700265}
266
zhihuang184a3fd2016-06-14 11:47:14 -0700267void AudioRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
268 observer_ = observer;
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700269 // Deliver any notifications the observer may have missed by being set late.
zhihuangc4adabf2016-12-07 10:36:40 -0800270 if (received_first_packet_ && observer_) {
zhihuang184a3fd2016-06-14 11:47:14 -0700271 observer_->OnFirstPacketReceived(media_type());
272 }
273}
274
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800275void AudioRtpReceiver::SetMediaChannel(cricket::MediaChannel* media_channel) {
276 RTC_DCHECK(media_channel == nullptr ||
277 media_channel->media_type() == media_type());
278 media_channel_ = static_cast<cricket::VoiceMediaChannel*>(media_channel);
Benjamin Wrightbfd412e2018-09-10 14:06:02 -0700279}
280
Steve Anton60776752018-01-10 11:51:34 -0800281void AudioRtpReceiver::NotifyFirstPacketReceived() {
zhihuang184a3fd2016-06-14 11:47:14 -0700282 if (observer_) {
283 observer_->OnFirstPacketReceived(media_type());
284 }
285 received_first_packet_ = true;
286}
287
Henrik Boström199e27b2018-07-04 20:51:53 +0200288VideoRtpReceiver::VideoRtpReceiver(rtc::Thread* worker_thread,
289 std::string receiver_id,
290 std::vector<std::string> stream_ids)
291 : VideoRtpReceiver(worker_thread,
292 receiver_id,
293 CreateStreamsFromIds(std::move(stream_ids))) {}
294
Henrik Boström9e6fd2b2017-11-21 13:41:51 +0100295VideoRtpReceiver::VideoRtpReceiver(
Steve Anton60776752018-01-10 11:51:34 -0800296 rtc::Thread* worker_thread,
Steve Antonef65ef12018-01-10 17:15:20 -0800297 const std::string& receiver_id,
Steve Antond3679212018-01-17 17:41:02 -0800298 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams)
Steve Anton60776752018-01-10 11:51:34 -0800299 : worker_thread_(worker_thread),
Steve Antonef65ef12018-01-10 17:15:20 -0800300 id_(receiver_id),
Niels Möller5d67f822018-05-23 16:28:17 +0200301 source_(new RefCountedObject<VideoRtpTrackSource>()),
perkjf0dcfe22016-03-10 18:32:00 +0100302 track_(VideoTrackProxy::Create(
303 rtc::Thread::Current(),
nisse5b68ab52016-04-07 07:45:54 -0700304 worker_thread,
305 VideoTrack::Create(
Steve Antonef65ef12018-01-10 17:15:20 -0800306 receiver_id,
nisse5b68ab52016-04-07 07:45:54 -0700307 VideoTrackSourceProxy::Create(rtc::Thread::Current(),
308 worker_thread,
perkj773be362017-07-31 23:22:01 -0700309 source_),
Harald Alvestrandc72af932018-01-11 17:18:19 +0100310 worker_thread))),
311 attachment_id_(GenerateUniqueId()) {
Steve Anton60776752018-01-10 11:51:34 -0800312 RTC_DCHECK(worker_thread_);
Steve Antonef65ef12018-01-10 17:15:20 -0800313 SetStreams(streams);
perkjf0dcfe22016-03-10 18:32:00 +0100314 source_->SetState(MediaSourceInterface::kLive);
deadbeef70ab1a12015-09-28 16:53:55 -0700315}
316
317VideoRtpReceiver::~VideoRtpReceiver() {
318 // Since cricket::VideoRenderer is not reference counted,
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700319 // we need to remove it from the channel before we are deleted.
deadbeef70ab1a12015-09-28 16:53:55 -0700320 Stop();
321}
322
Henrik Boström199e27b2018-07-04 20:51:53 +0200323std::vector<std::string> VideoRtpReceiver::stream_ids() const {
324 std::vector<std::string> stream_ids(streams_.size());
325 for (size_t i = 0; i < streams_.size(); ++i)
326 stream_ids[i] = streams_[i]->id();
327 return stream_ids;
328}
329
Steve Anton60776752018-01-10 11:51:34 -0800330bool VideoRtpReceiver::SetSink(rtc::VideoSinkInterface<VideoFrame>* sink) {
331 RTC_DCHECK(media_channel_);
Steve Antond3679212018-01-17 17:41:02 -0800332 RTC_DCHECK(ssrc_);
Steve Anton60776752018-01-10 11:51:34 -0800333 return worker_thread_->Invoke<bool>(
Steve Antond3679212018-01-17 17:41:02 -0800334 RTC_FROM_HERE, [&] { return media_channel_->SetSink(*ssrc_, sink); });
Steve Anton60776752018-01-10 11:51:34 -0800335}
336
deadbeefa601f5c2016-06-06 14:27:39 -0700337RtpParameters VideoRtpReceiver::GetParameters() const {
Steve Antond3679212018-01-17 17:41:02 -0800338 if (!media_channel_ || !ssrc_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700339 return RtpParameters();
340 }
Steve Anton60776752018-01-10 11:51:34 -0800341 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
Steve Antond3679212018-01-17 17:41:02 -0800342 return media_channel_->GetRtpReceiveParameters(*ssrc_);
Steve Anton60776752018-01-10 11:51:34 -0800343 });
deadbeefa601f5c2016-06-06 14:27:39 -0700344}
345
346bool VideoRtpReceiver::SetParameters(const RtpParameters& parameters) {
347 TRACE_EVENT0("webrtc", "VideoRtpReceiver::SetParameters");
Steve Antond3679212018-01-17 17:41:02 -0800348 if (!media_channel_ || !ssrc_ || stopped_) {
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700349 return false;
350 }
Steve Anton60776752018-01-10 11:51:34 -0800351 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
Steve Antond3679212018-01-17 17:41:02 -0800352 return media_channel_->SetRtpReceiveParameters(*ssrc_, parameters);
Steve Anton60776752018-01-10 11:51:34 -0800353 });
deadbeefa601f5c2016-06-06 14:27:39 -0700354}
355
Benjamin Wrightd81ac952018-08-29 17:02:10 -0700356void VideoRtpReceiver::SetFrameDecryptor(
357 rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
358 frame_decryptor_ = std::move(frame_decryptor);
Benjamin Wright6cc9cca2018-10-09 17:29:54 -0700359 // Special Case: Set the frame decryptor to any value on any existing channel.
Benjamin Wrightc462a6e2018-10-26 13:16:16 -0700360 if (media_channel_ && ssrc_.has_value() && !stopped_) {
Benjamin Wright6cc9cca2018-10-09 17:29:54 -0700361 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
362 media_channel_->SetFrameDecryptor(*ssrc_, frame_decryptor_);
363 });
364 }
Benjamin Wrightd81ac952018-08-29 17:02:10 -0700365}
366
367rtc::scoped_refptr<FrameDecryptorInterface>
368VideoRtpReceiver::GetFrameDecryptor() const {
369 return frame_decryptor_;
370}
371
deadbeef70ab1a12015-09-28 16:53:55 -0700372void VideoRtpReceiver::Stop() {
373 // TODO(deadbeef): Need to do more here to fully stop receiving packets.
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700374 if (stopped_) {
deadbeef70ab1a12015-09-28 16:53:55 -0700375 return;
376 }
perkjf0dcfe22016-03-10 18:32:00 +0100377 source_->SetState(MediaSourceInterface::kEnded);
Steve Antond3679212018-01-17 17:41:02 -0800378 if (!media_channel_ || !ssrc_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100379 RTC_LOG(LS_WARNING) << "VideoRtpReceiver::Stop: No video channel exists.";
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700380 } else {
381 // Allow that SetSink fail. This is the normal case when the underlying
382 // media channel has already been deleted.
Steve Anton60776752018-01-10 11:51:34 -0800383 SetSink(nullptr);
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700384 }
385 stopped_ = true;
deadbeef70ab1a12015-09-28 16:53:55 -0700386}
387
Steve Antond3679212018-01-17 17:41:02 -0800388void VideoRtpReceiver::SetupMediaChannel(uint32_t ssrc) {
389 if (!media_channel_) {
390 RTC_LOG(LS_ERROR)
391 << "VideoRtpReceiver::SetupMediaChannel: No video channel exists.";
392 }
393 if (ssrc_ == ssrc) {
394 return;
395 }
396 if (ssrc_) {
397 SetSink(nullptr);
398 }
399 ssrc_ = ssrc;
Niels Möller5d67f822018-05-23 16:28:17 +0200400 SetSink(source_->sink());
Benjamin Wright84583f62018-10-04 14:22:34 -0700401 // Attach any existing frame decryptor to the media channel.
Benjamin Wrightc462a6e2018-10-26 13:16:16 -0700402 MaybeAttachFrameDecryptorToMediaChannel(
403 ssrc_, worker_thread_, frame_decryptor_, media_channel_, stopped_);
Steve Antond3679212018-01-17 17:41:02 -0800404}
405
Henrik Boström199e27b2018-07-04 20:51:53 +0200406void VideoRtpReceiver::set_stream_ids(std::vector<std::string> stream_ids) {
407 SetStreams(CreateStreamsFromIds(std::move(stream_ids)));
408}
409
Steve Antonef65ef12018-01-10 17:15:20 -0800410void VideoRtpReceiver::SetStreams(
411 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
412 // Remove remote track from any streams that are going away.
413 for (auto existing_stream : streams_) {
414 bool removed = true;
415 for (auto stream : streams) {
Seth Hampson13b8bad2018-03-13 16:05:28 -0700416 if (existing_stream->id() == stream->id()) {
Steve Antonef65ef12018-01-10 17:15:20 -0800417 RTC_DCHECK_EQ(existing_stream.get(), stream.get());
418 removed = false;
419 break;
420 }
421 }
422 if (removed) {
423 existing_stream->RemoveTrack(track_);
424 }
425 }
426 // Add remote track to any streams that are new.
427 for (auto stream : streams) {
428 bool added = true;
429 for (auto existing_stream : streams_) {
Seth Hampson13b8bad2018-03-13 16:05:28 -0700430 if (stream->id() == existing_stream->id()) {
Steve Antonef65ef12018-01-10 17:15:20 -0800431 RTC_DCHECK_EQ(stream.get(), existing_stream.get());
432 added = false;
433 break;
434 }
435 }
436 if (added) {
437 stream->AddTrack(track_);
438 }
439 }
440 streams_ = streams;
441}
442
zhihuang184a3fd2016-06-14 11:47:14 -0700443void VideoRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
444 observer_ = observer;
Taylor Brandstetterba29c6a2016-06-27 16:30:35 -0700445 // Deliver any notifications the observer may have missed by being set late.
zhihuangc4adabf2016-12-07 10:36:40 -0800446 if (received_first_packet_ && observer_) {
zhihuang184a3fd2016-06-14 11:47:14 -0700447 observer_->OnFirstPacketReceived(media_type());
448 }
449}
450
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800451void VideoRtpReceiver::SetMediaChannel(cricket::MediaChannel* media_channel) {
452 RTC_DCHECK(media_channel == nullptr ||
453 media_channel->media_type() == media_type());
454 media_channel_ = static_cast<cricket::VideoMediaChannel*>(media_channel);
Benjamin Wrightbfd412e2018-09-10 14:06:02 -0700455}
456
Steve Anton60776752018-01-10 11:51:34 -0800457void VideoRtpReceiver::NotifyFirstPacketReceived() {
zhihuang184a3fd2016-06-14 11:47:14 -0700458 if (observer_) {
459 observer_->OnFirstPacketReceived(media_type());
460 }
461 received_first_packet_ = true;
462}
463
Jonas Oreland49ac5952018-09-26 16:04:32 +0200464std::vector<RtpSource> VideoRtpReceiver::GetSources() const {
465 if (!media_channel_ || !ssrc_ || stopped_) {
466 return {};
467 }
468 return worker_thread_->Invoke<std::vector<RtpSource>>(
469 RTC_FROM_HERE, [&] { return media_channel_->GetSources(*ssrc_); });
470}
471
deadbeef70ab1a12015-09-28 16:53:55 -0700472} // namespace webrtc