blob: e6de6c71b3d10aeeb7576036e1f888e04f974b8a [file] [log] [blame]
Ruslan Burakov501bfba2019-02-11 10:29:19 +01001/*
2 * Copyright 2019 The WebRTC project authors. All Rights Reserved.
3 *
4 * 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.
9 */
10
11#include "pc/video_rtp_receiver.h"
12
13#include <stddef.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020014
Ruslan Burakov501bfba2019-02-11 10:29:19 +010015#include <utility>
16#include <vector>
17
18#include "api/media_stream_proxy.h"
19#include "api/media_stream_track_proxy.h"
20#include "api/video_track_source_proxy.h"
Ruslan Burakov428dcb22019-04-18 17:49:49 +020021#include "pc/jitter_buffer_delay.h"
22#include "pc/jitter_buffer_delay_proxy.h"
Ruslan Burakov501bfba2019-02-11 10:29:19 +010023#include "pc/media_stream.h"
24#include "pc/video_track.h"
25#include "rtc_base/checks.h"
26#include "rtc_base/location.h"
27#include "rtc_base/logging.h"
28#include "rtc_base/trace_event.h"
29
30namespace webrtc {
31
32VideoRtpReceiver::VideoRtpReceiver(rtc::Thread* worker_thread,
33 std::string receiver_id,
34 std::vector<std::string> stream_ids)
35 : VideoRtpReceiver(worker_thread,
36 receiver_id,
37 CreateStreamsFromIds(std::move(stream_ids))) {}
38
39VideoRtpReceiver::VideoRtpReceiver(
40 rtc::Thread* worker_thread,
41 const std::string& receiver_id,
42 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams)
43 : worker_thread_(worker_thread),
44 id_(receiver_id),
Ruslan Burakov428dcb22019-04-18 17:49:49 +020045 source_(new RefCountedObject<VideoRtpTrackSource>()),
Ruslan Burakov501bfba2019-02-11 10:29:19 +010046 track_(VideoTrackProxy::Create(
47 rtc::Thread::Current(),
48 worker_thread,
49 VideoTrack::Create(
50 receiver_id,
51 VideoTrackSourceProxy::Create(rtc::Thread::Current(),
52 worker_thread,
53 source_),
54 worker_thread))),
Ruslan Burakov428dcb22019-04-18 17:49:49 +020055 attachment_id_(GenerateUniqueId()),
56 delay_(JitterBufferDelayProxy::Create(
57 rtc::Thread::Current(),
58 worker_thread,
59 new rtc::RefCountedObject<JitterBufferDelay>(worker_thread))) {
Ruslan Burakov501bfba2019-02-11 10:29:19 +010060 RTC_DCHECK(worker_thread_);
61 SetStreams(streams);
62 source_->SetState(MediaSourceInterface::kLive);
63}
64
65VideoRtpReceiver::~VideoRtpReceiver() {
66 // Since cricket::VideoRenderer is not reference counted,
67 // we need to remove it from the channel before we are deleted.
68 Stop();
69}
70
71std::vector<std::string> VideoRtpReceiver::stream_ids() const {
72 std::vector<std::string> stream_ids(streams_.size());
73 for (size_t i = 0; i < streams_.size(); ++i)
74 stream_ids[i] = streams_[i]->id();
75 return stream_ids;
76}
77
78bool VideoRtpReceiver::SetSink(rtc::VideoSinkInterface<VideoFrame>* sink) {
79 RTC_DCHECK(media_channel_);
Saurav Das7262fc22019-09-11 16:23:05 -070080 RTC_DCHECK(!stopped_);
81 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
82 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
83 return media_channel_->SetSink(ssrc_.value_or(0), sink);
84 });
Ruslan Burakov501bfba2019-02-11 10:29:19 +010085}
86
87RtpParameters VideoRtpReceiver::GetParameters() const {
Saurav Das7262fc22019-09-11 16:23:05 -070088 if (!media_channel_ || stopped_) {
Ruslan Burakov501bfba2019-02-11 10:29:19 +010089 return RtpParameters();
90 }
91 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
Saurav Das7262fc22019-09-11 16:23:05 -070092 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
93 return media_channel_->GetRtpReceiveParameters(ssrc_.value_or(0));
Ruslan Burakov501bfba2019-02-11 10:29:19 +010094 });
95}
96
97bool VideoRtpReceiver::SetParameters(const RtpParameters& parameters) {
98 TRACE_EVENT0("webrtc", "VideoRtpReceiver::SetParameters");
Saurav Das7262fc22019-09-11 16:23:05 -070099 if (!media_channel_ || stopped_) {
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100100 return false;
101 }
102 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
Saurav Das7262fc22019-09-11 16:23:05 -0700103 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
104 return media_channel_->SetRtpReceiveParameters(ssrc_.value_or(0),
105 parameters);
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100106 });
107}
108
109void VideoRtpReceiver::SetFrameDecryptor(
110 rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
111 frame_decryptor_ = std::move(frame_decryptor);
112 // Special Case: Set the frame decryptor to any value on any existing channel.
113 if (media_channel_ && ssrc_.has_value() && !stopped_) {
114 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
115 media_channel_->SetFrameDecryptor(*ssrc_, frame_decryptor_);
116 });
117 }
118}
119
120rtc::scoped_refptr<FrameDecryptorInterface>
121VideoRtpReceiver::GetFrameDecryptor() const {
122 return frame_decryptor_;
123}
124
125void VideoRtpReceiver::Stop() {
126 // TODO(deadbeef): Need to do more here to fully stop receiving packets.
127 if (stopped_) {
128 return;
129 }
130 source_->SetState(MediaSourceInterface::kEnded);
Saurav Das7262fc22019-09-11 16:23:05 -0700131 if (!media_channel_) {
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100132 RTC_LOG(LS_WARNING) << "VideoRtpReceiver::Stop: No video channel exists.";
133 } else {
134 // Allow that SetSink fail. This is the normal case when the underlying
135 // media channel has already been deleted.
136 SetSink(nullptr);
137 }
Ruslan Burakov428dcb22019-04-18 17:49:49 +0200138 delay_->OnStop();
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100139 stopped_ = true;
140}
141
Saurav Das7262fc22019-09-11 16:23:05 -0700142void VideoRtpReceiver::RestartMediaChannel(absl::optional<uint32_t> ssrc) {
143 RTC_DCHECK(media_channel_);
144 if (!stopped_ && ssrc_ == ssrc) {
145 return;
146 }
147 if (!stopped_) {
148 SetSink(nullptr);
149 }
150 stopped_ = false;
151 ssrc_ = ssrc;
152 SetSink(source_->sink());
153
154 // Attach any existing frame decryptor to the media channel.
155 MaybeAttachFrameDecryptorToMediaChannel(
156 ssrc, worker_thread_, frame_decryptor_, media_channel_, stopped_);
157 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
158 // value.
159 delay_->OnStart(media_channel_, ssrc.value_or(0));
160}
161
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100162void VideoRtpReceiver::SetupMediaChannel(uint32_t ssrc) {
163 if (!media_channel_) {
164 RTC_LOG(LS_ERROR)
165 << "VideoRtpReceiver::SetupMediaChannel: No video channel exists.";
166 }
Saurav Das7262fc22019-09-11 16:23:05 -0700167 RestartMediaChannel(ssrc);
168}
Ruslan Burakov493a6502019-02-27 15:32:48 +0100169
Saurav Das7262fc22019-09-11 16:23:05 -0700170void VideoRtpReceiver::SetupUnsignaledMediaChannel() {
171 if (!media_channel_) {
172 RTC_LOG(LS_ERROR) << "VideoRtpReceiver::SetupUnsignaledMediaChannel: No "
173 "video channel exists.";
174 }
175 RestartMediaChannel(absl::nullopt);
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100176}
177
178void VideoRtpReceiver::set_stream_ids(std::vector<std::string> stream_ids) {
179 SetStreams(CreateStreamsFromIds(std::move(stream_ids)));
180}
181
182void VideoRtpReceiver::SetStreams(
183 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
184 // Remove remote track from any streams that are going away.
185 for (const auto& existing_stream : streams_) {
186 bool removed = true;
187 for (const auto& stream : streams) {
188 if (existing_stream->id() == stream->id()) {
189 RTC_DCHECK_EQ(existing_stream.get(), stream.get());
190 removed = false;
191 break;
192 }
193 }
194 if (removed) {
195 existing_stream->RemoveTrack(track_);
196 }
197 }
198 // Add remote track to any streams that are new.
199 for (const auto& stream : streams) {
200 bool added = true;
201 for (const auto& existing_stream : streams_) {
202 if (stream->id() == existing_stream->id()) {
203 RTC_DCHECK_EQ(stream.get(), existing_stream.get());
204 added = false;
205 break;
206 }
207 }
208 if (added) {
209 stream->AddTrack(track_);
210 }
211 }
212 streams_ = streams;
213}
214
215void VideoRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
216 observer_ = observer;
217 // Deliver any notifications the observer may have missed by being set late.
218 if (received_first_packet_ && observer_) {
219 observer_->OnFirstPacketReceived(media_type());
220 }
221}
222
Ruslan Burakov4bac79e2019-04-03 19:55:33 +0200223void VideoRtpReceiver::SetJitterBufferMinimumDelay(
224 absl::optional<double> delay_seconds) {
Ruslan Burakov428dcb22019-04-18 17:49:49 +0200225 delay_->Set(delay_seconds);
Ruslan Burakov4bac79e2019-04-03 19:55:33 +0200226}
227
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100228void VideoRtpReceiver::SetMediaChannel(cricket::MediaChannel* media_channel) {
229 RTC_DCHECK(media_channel == nullptr ||
230 media_channel->media_type() == media_type());
231 media_channel_ = static_cast<cricket::VideoMediaChannel*>(media_channel);
232}
233
234void VideoRtpReceiver::NotifyFirstPacketReceived() {
235 if (observer_) {
236 observer_->OnFirstPacketReceived(media_type());
237 }
238 received_first_packet_ = true;
239}
240
241std::vector<RtpSource> VideoRtpReceiver::GetSources() const {
242 if (!media_channel_ || !ssrc_ || stopped_) {
243 return {};
244 }
245 return worker_thread_->Invoke<std::vector<RtpSource>>(
246 RTC_FROM_HERE, [&] { return media_channel_->GetSources(*ssrc_); });
247}
248
249} // namespace webrtc