1 /*
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>
14
15 #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"
21 #include "pc/jitter_buffer_delay.h"
22 #include "pc/jitter_buffer_delay_proxy.h"
23 #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
30 namespace webrtc {
31
VideoRtpReceiver(rtc::Thread * worker_thread,std::string receiver_id,std::vector<std::string> stream_ids)32 VideoRtpReceiver::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
VideoRtpReceiver(rtc::Thread * worker_thread,const std::string & receiver_id,const std::vector<rtc::scoped_refptr<MediaStreamInterface>> & streams)39 VideoRtpReceiver::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),
45 source_(new RefCountedObject<VideoRtpTrackSource>(this)),
46 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))),
55 attachment_id_(GenerateUniqueId()),
56 delay_(JitterBufferDelayProxy::Create(
57 rtc::Thread::Current(),
58 worker_thread,
59 new rtc::RefCountedObject<JitterBufferDelay>(worker_thread))) {
60 RTC_DCHECK(worker_thread_);
61 SetStreams(streams);
62 source_->SetState(MediaSourceInterface::kLive);
63 }
64
~VideoRtpReceiver()65 VideoRtpReceiver::~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 // Make sure we can't be called by the |source_| anymore.
70 worker_thread_->Invoke<void>(RTC_FROM_HERE,
71 [this] { source_->ClearCallback(); });
72 }
73
stream_ids() const74 std::vector<std::string> VideoRtpReceiver::stream_ids() const {
75 std::vector<std::string> stream_ids(streams_.size());
76 for (size_t i = 0; i < streams_.size(); ++i)
77 stream_ids[i] = streams_[i]->id();
78 return stream_ids;
79 }
80
GetParameters() const81 RtpParameters VideoRtpReceiver::GetParameters() const {
82 if (!media_channel_ || stopped_) {
83 return RtpParameters();
84 }
85 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
86 return ssrc_ ? media_channel_->GetRtpReceiveParameters(*ssrc_)
87 : media_channel_->GetDefaultRtpReceiveParameters();
88 });
89 }
90
SetFrameDecryptor(rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor)91 void VideoRtpReceiver::SetFrameDecryptor(
92 rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
93 frame_decryptor_ = std::move(frame_decryptor);
94 // Special Case: Set the frame decryptor to any value on any existing channel.
95 if (media_channel_ && ssrc_.has_value() && !stopped_) {
96 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
97 media_channel_->SetFrameDecryptor(*ssrc_, frame_decryptor_);
98 });
99 }
100 }
101
102 rtc::scoped_refptr<FrameDecryptorInterface>
GetFrameDecryptor() const103 VideoRtpReceiver::GetFrameDecryptor() const {
104 return frame_decryptor_;
105 }
106
SetDepacketizerToDecoderFrameTransformer(rtc::scoped_refptr<FrameTransformerInterface> frame_transformer)107 void VideoRtpReceiver::SetDepacketizerToDecoderFrameTransformer(
108 rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) {
109 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
110 RTC_DCHECK_RUN_ON(worker_thread_);
111 frame_transformer_ = std::move(frame_transformer);
112 if (media_channel_ && !stopped_) {
113 media_channel_->SetDepacketizerToDecoderFrameTransformer(
114 ssrc_.value_or(0), frame_transformer_);
115 }
116 });
117 }
118
Stop()119 void VideoRtpReceiver::Stop() {
120 // TODO(deadbeef): Need to do more here to fully stop receiving packets.
121 if (stopped_) {
122 return;
123 }
124 source_->SetState(MediaSourceInterface::kEnded);
125 if (!media_channel_) {
126 RTC_LOG(LS_WARNING) << "VideoRtpReceiver::Stop: No video channel exists.";
127 } else {
128 // Allow that SetSink fails. This is the normal case when the underlying
129 // media channel has already been deleted.
130 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
131 RTC_DCHECK_RUN_ON(worker_thread_);
132 SetSink(nullptr);
133 });
134 }
135 delay_->OnStop();
136 stopped_ = true;
137 }
138
RestartMediaChannel(absl::optional<uint32_t> ssrc)139 void VideoRtpReceiver::RestartMediaChannel(absl::optional<uint32_t> ssrc) {
140 RTC_DCHECK(media_channel_);
141 if (!stopped_ && ssrc_ == ssrc) {
142 return;
143 }
144 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
145 RTC_DCHECK_RUN_ON(worker_thread_);
146 if (!stopped_) {
147 SetSink(nullptr);
148 }
149 bool encoded_sink_enabled = saved_encoded_sink_enabled_;
150 SetEncodedSinkEnabled(false);
151 stopped_ = false;
152
153 ssrc_ = ssrc;
154
155 SetSink(source_->sink());
156 if (encoded_sink_enabled) {
157 SetEncodedSinkEnabled(true);
158 }
159
160 if (frame_transformer_ && media_channel_) {
161 media_channel_->SetDepacketizerToDecoderFrameTransformer(
162 ssrc_.value_or(0), frame_transformer_);
163 }
164 });
165
166 // Attach any existing frame decryptor to the media channel.
167 MaybeAttachFrameDecryptorToMediaChannel(
168 ssrc, worker_thread_, frame_decryptor_, media_channel_, stopped_);
169 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
170 // value.
171 delay_->OnStart(media_channel_, ssrc.value_or(0));
172 }
173
SetSink(rtc::VideoSinkInterface<VideoFrame> * sink)174 void VideoRtpReceiver::SetSink(rtc::VideoSinkInterface<VideoFrame>* sink) {
175 RTC_DCHECK(media_channel_);
176 if (ssrc_) {
177 media_channel_->SetSink(*ssrc_, sink);
178 return;
179 }
180 media_channel_->SetDefaultSink(sink);
181 }
182
SetupMediaChannel(uint32_t ssrc)183 void VideoRtpReceiver::SetupMediaChannel(uint32_t ssrc) {
184 if (!media_channel_) {
185 RTC_LOG(LS_ERROR)
186 << "VideoRtpReceiver::SetupMediaChannel: No video channel exists.";
187 }
188 RestartMediaChannel(ssrc);
189 }
190
SetupUnsignaledMediaChannel()191 void VideoRtpReceiver::SetupUnsignaledMediaChannel() {
192 if (!media_channel_) {
193 RTC_LOG(LS_ERROR) << "VideoRtpReceiver::SetupUnsignaledMediaChannel: No "
194 "video channel exists.";
195 }
196 RestartMediaChannel(absl::nullopt);
197 }
198
set_stream_ids(std::vector<std::string> stream_ids)199 void VideoRtpReceiver::set_stream_ids(std::vector<std::string> stream_ids) {
200 SetStreams(CreateStreamsFromIds(std::move(stream_ids)));
201 }
202
SetStreams(const std::vector<rtc::scoped_refptr<MediaStreamInterface>> & streams)203 void VideoRtpReceiver::SetStreams(
204 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
205 // Remove remote track from any streams that are going away.
206 for (const auto& existing_stream : streams_) {
207 bool removed = true;
208 for (const auto& stream : streams) {
209 if (existing_stream->id() == stream->id()) {
210 RTC_DCHECK_EQ(existing_stream.get(), stream.get());
211 removed = false;
212 break;
213 }
214 }
215 if (removed) {
216 existing_stream->RemoveTrack(track_);
217 }
218 }
219 // Add remote track to any streams that are new.
220 for (const auto& stream : streams) {
221 bool added = true;
222 for (const auto& existing_stream : streams_) {
223 if (stream->id() == existing_stream->id()) {
224 RTC_DCHECK_EQ(stream.get(), existing_stream.get());
225 added = false;
226 break;
227 }
228 }
229 if (added) {
230 stream->AddTrack(track_);
231 }
232 }
233 streams_ = streams;
234 }
235
SetObserver(RtpReceiverObserverInterface * observer)236 void VideoRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
237 observer_ = observer;
238 // Deliver any notifications the observer may have missed by being set late.
239 if (received_first_packet_ && observer_) {
240 observer_->OnFirstPacketReceived(media_type());
241 }
242 }
243
SetJitterBufferMinimumDelay(absl::optional<double> delay_seconds)244 void VideoRtpReceiver::SetJitterBufferMinimumDelay(
245 absl::optional<double> delay_seconds) {
246 delay_->Set(delay_seconds);
247 }
248
SetMediaChannel(cricket::MediaChannel * media_channel)249 void VideoRtpReceiver::SetMediaChannel(cricket::MediaChannel* media_channel) {
250 RTC_DCHECK(media_channel == nullptr ||
251 media_channel->media_type() == media_type());
252 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
253 RTC_DCHECK_RUN_ON(worker_thread_);
254 bool encoded_sink_enabled = saved_encoded_sink_enabled_;
255 if (encoded_sink_enabled && media_channel_) {
256 // Turn off the old sink, if any.
257 SetEncodedSinkEnabled(false);
258 }
259
260 media_channel_ = static_cast<cricket::VideoMediaChannel*>(media_channel);
261
262 if (media_channel_) {
263 if (saved_generate_keyframe_) {
264 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
265 media_channel_->GenerateKeyFrame(ssrc_.value_or(0));
266 saved_generate_keyframe_ = false;
267 }
268 if (encoded_sink_enabled) {
269 SetEncodedSinkEnabled(true);
270 }
271 if (frame_transformer_) {
272 media_channel_->SetDepacketizerToDecoderFrameTransformer(
273 ssrc_.value_or(0), frame_transformer_);
274 }
275 }
276 });
277 }
278
NotifyFirstPacketReceived()279 void VideoRtpReceiver::NotifyFirstPacketReceived() {
280 if (observer_) {
281 observer_->OnFirstPacketReceived(media_type());
282 }
283 received_first_packet_ = true;
284 }
285
GetSources() const286 std::vector<RtpSource> VideoRtpReceiver::GetSources() const {
287 if (!media_channel_ || !ssrc_ || stopped_) {
288 return {};
289 }
290 return worker_thread_->Invoke<std::vector<RtpSource>>(
291 RTC_FROM_HERE, [&] { return media_channel_->GetSources(*ssrc_); });
292 }
293
OnGenerateKeyFrame()294 void VideoRtpReceiver::OnGenerateKeyFrame() {
295 RTC_DCHECK_RUN_ON(worker_thread_);
296 if (!media_channel_) {
297 RTC_LOG(LS_ERROR)
298 << "VideoRtpReceiver::OnGenerateKeyFrame: No video channel exists.";
299 return;
300 }
301 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
302 media_channel_->GenerateKeyFrame(ssrc_.value_or(0));
303 // We need to remember to request generation of a new key frame if the media
304 // channel changes, because there's no feedback whether the keyframe
305 // generation has completed on the channel.
306 saved_generate_keyframe_ = true;
307 }
308
OnEncodedSinkEnabled(bool enable)309 void VideoRtpReceiver::OnEncodedSinkEnabled(bool enable) {
310 RTC_DCHECK_RUN_ON(worker_thread_);
311 SetEncodedSinkEnabled(enable);
312 // Always save the latest state of the callback in case the media_channel_
313 // changes.
314 saved_encoded_sink_enabled_ = enable;
315 }
316
SetEncodedSinkEnabled(bool enable)317 void VideoRtpReceiver::SetEncodedSinkEnabled(bool enable) {
318 if (media_channel_) {
319 if (enable) {
320 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
321 auto source = source_;
322 media_channel_->SetRecordableEncodedFrameCallback(
323 ssrc_.value_or(0),
324 [source = std::move(source)](const RecordableEncodedFrame& frame) {
325 source->BroadcastRecordableEncodedFrame(frame);
326 });
327 } else {
328 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
329 media_channel_->ClearRecordableEncodedFrameCallback(ssrc_.value_or(0));
330 }
331 }
332 }
333
334 } // namespace webrtc
335