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 <string>
16 #include <utility>
17 #include <vector>
18
19 #include "api/video/recordable_encoded_frame.h"
20 #include "pc/video_track.h"
21 #include "rtc_base/checks.h"
22 #include "rtc_base/logging.h"
23
24 namespace webrtc {
25
VideoRtpReceiver(rtc::Thread * worker_thread,std::string receiver_id,std::vector<std::string> stream_ids)26 VideoRtpReceiver::VideoRtpReceiver(rtc::Thread* worker_thread,
27 std::string receiver_id,
28 std::vector<std::string> stream_ids)
29 : VideoRtpReceiver(worker_thread,
30 receiver_id,
31 CreateStreamsFromIds(std::move(stream_ids))) {}
32
VideoRtpReceiver(rtc::Thread * worker_thread,const std::string & receiver_id,const std::vector<rtc::scoped_refptr<MediaStreamInterface>> & streams)33 VideoRtpReceiver::VideoRtpReceiver(
34 rtc::Thread* worker_thread,
35 const std::string& receiver_id,
36 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams)
37 : worker_thread_(worker_thread),
38 id_(receiver_id),
39 source_(rtc::make_ref_counted<VideoRtpTrackSource>(&source_callback_)),
40 track_(VideoTrackProxyWithInternal<VideoTrack>::Create(
41 rtc::Thread::Current(),
42 worker_thread,
43 VideoTrack::Create(receiver_id, source_, worker_thread))),
44 attachment_id_(GenerateUniqueId()) {
45 RTC_DCHECK(worker_thread_);
46 SetStreams(streams);
47 RTC_DCHECK_EQ(source_->state(), MediaSourceInterface::kInitializing);
48 }
49
~VideoRtpReceiver()50 VideoRtpReceiver::~VideoRtpReceiver() {
51 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
52 RTC_DCHECK(!media_channel_);
53 }
54
stream_ids() const55 std::vector<std::string> VideoRtpReceiver::stream_ids() const {
56 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
57 std::vector<std::string> stream_ids(streams_.size());
58 for (size_t i = 0; i < streams_.size(); ++i)
59 stream_ids[i] = streams_[i]->id();
60 return stream_ids;
61 }
62
dtls_transport() const63 rtc::scoped_refptr<DtlsTransportInterface> VideoRtpReceiver::dtls_transport()
64 const {
65 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
66 return dtls_transport_;
67 }
68
69 std::vector<rtc::scoped_refptr<MediaStreamInterface>>
streams() const70 VideoRtpReceiver::streams() const {
71 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
72 return streams_;
73 }
74
GetParameters() const75 RtpParameters VideoRtpReceiver::GetParameters() const {
76 RTC_DCHECK_RUN_ON(worker_thread_);
77 if (!media_channel_)
78 return RtpParameters();
79 return ssrc_ ? media_channel_->GetRtpReceiveParameters(*ssrc_)
80 : media_channel_->GetDefaultRtpReceiveParameters();
81 }
82
SetFrameDecryptor(rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor)83 void VideoRtpReceiver::SetFrameDecryptor(
84 rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
85 RTC_DCHECK_RUN_ON(worker_thread_);
86 frame_decryptor_ = std::move(frame_decryptor);
87 // Special Case: Set the frame decryptor to any value on any existing channel.
88 if (media_channel_ && ssrc_) {
89 media_channel_->SetFrameDecryptor(*ssrc_, frame_decryptor_);
90 }
91 }
92
93 rtc::scoped_refptr<FrameDecryptorInterface>
GetFrameDecryptor() const94 VideoRtpReceiver::GetFrameDecryptor() const {
95 RTC_DCHECK_RUN_ON(worker_thread_);
96 return frame_decryptor_;
97 }
98
SetDepacketizerToDecoderFrameTransformer(rtc::scoped_refptr<FrameTransformerInterface> frame_transformer)99 void VideoRtpReceiver::SetDepacketizerToDecoderFrameTransformer(
100 rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) {
101 RTC_DCHECK_RUN_ON(worker_thread_);
102 frame_transformer_ = std::move(frame_transformer);
103 if (media_channel_) {
104 media_channel_->SetDepacketizerToDecoderFrameTransformer(
105 ssrc_.value_or(0), frame_transformer_);
106 }
107 }
108
Stop()109 void VideoRtpReceiver::Stop() {
110 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
111 source_->SetState(MediaSourceInterface::kEnded);
112 track_->internal()->set_ended();
113 }
114
RestartMediaChannel(absl::optional<uint32_t> ssrc)115 void VideoRtpReceiver::RestartMediaChannel(absl::optional<uint32_t> ssrc) {
116 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
117 MediaSourceInterface::SourceState state = source_->state();
118 // TODO(tommi): Can we restart the media channel without blocking?
119 worker_thread_->BlockingCall([&] {
120 RTC_DCHECK_RUN_ON(worker_thread_);
121 RestartMediaChannel_w(std::move(ssrc), state);
122 });
123 source_->SetState(MediaSourceInterface::kLive);
124 }
125
RestartMediaChannel_w(absl::optional<uint32_t> ssrc,MediaSourceInterface::SourceState state)126 void VideoRtpReceiver::RestartMediaChannel_w(
127 absl::optional<uint32_t> ssrc,
128 MediaSourceInterface::SourceState state) {
129 RTC_DCHECK_RUN_ON(worker_thread_);
130 if (!media_channel_) {
131 return; // Can't restart.
132 }
133
134 const bool encoded_sink_enabled = saved_encoded_sink_enabled_;
135
136 if (state != MediaSourceInterface::kInitializing) {
137 if (ssrc == ssrc_)
138 return;
139
140 // Disconnect from a previous ssrc.
141 SetSink(nullptr);
142
143 if (encoded_sink_enabled)
144 SetEncodedSinkEnabled(false);
145 }
146
147 // Set up the new ssrc.
148 ssrc_ = std::move(ssrc);
149 SetSink(source_->sink());
150 if (encoded_sink_enabled) {
151 SetEncodedSinkEnabled(true);
152 }
153
154 if (frame_transformer_ && media_channel_) {
155 media_channel_->SetDepacketizerToDecoderFrameTransformer(
156 ssrc_.value_or(0), frame_transformer_);
157 }
158
159 if (media_channel_ && ssrc_) {
160 if (frame_decryptor_) {
161 media_channel_->SetFrameDecryptor(*ssrc_, frame_decryptor_);
162 }
163
164 media_channel_->SetBaseMinimumPlayoutDelayMs(*ssrc_, delay_.GetMs());
165 }
166 }
167
SetSink(rtc::VideoSinkInterface<VideoFrame> * sink)168 void VideoRtpReceiver::SetSink(rtc::VideoSinkInterface<VideoFrame>* sink) {
169 RTC_DCHECK_RUN_ON(worker_thread_);
170 if (ssrc_) {
171 media_channel_->SetSink(*ssrc_, sink);
172 } else {
173 media_channel_->SetDefaultSink(sink);
174 }
175 }
176
SetupMediaChannel(uint32_t ssrc)177 void VideoRtpReceiver::SetupMediaChannel(uint32_t ssrc) {
178 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
179 RestartMediaChannel(ssrc);
180 }
181
SetupUnsignaledMediaChannel()182 void VideoRtpReceiver::SetupUnsignaledMediaChannel() {
183 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
184 RestartMediaChannel(absl::nullopt);
185 }
186
ssrc() const187 uint32_t VideoRtpReceiver::ssrc() const {
188 RTC_DCHECK_RUN_ON(worker_thread_);
189 return ssrc_.value_or(0);
190 }
191
set_stream_ids(std::vector<std::string> stream_ids)192 void VideoRtpReceiver::set_stream_ids(std::vector<std::string> stream_ids) {
193 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
194 SetStreams(CreateStreamsFromIds(std::move(stream_ids)));
195 }
196
set_transport(rtc::scoped_refptr<DtlsTransportInterface> dtls_transport)197 void VideoRtpReceiver::set_transport(
198 rtc::scoped_refptr<DtlsTransportInterface> dtls_transport) {
199 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
200 dtls_transport_ = std::move(dtls_transport);
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 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
206 // Remove remote track from any streams that are going away.
207 for (const auto& existing_stream : streams_) {
208 bool removed = true;
209 for (const auto& stream : streams) {
210 if (existing_stream->id() == stream->id()) {
211 RTC_DCHECK_EQ(existing_stream.get(), stream.get());
212 removed = false;
213 break;
214 }
215 }
216 if (removed) {
217 existing_stream->RemoveTrack(video_track());
218 }
219 }
220 // Add remote track to any streams that are new.
221 for (const auto& stream : streams) {
222 bool added = true;
223 for (const auto& existing_stream : streams_) {
224 if (stream->id() == existing_stream->id()) {
225 RTC_DCHECK_EQ(stream.get(), existing_stream.get());
226 added = false;
227 break;
228 }
229 }
230 if (added) {
231 stream->AddTrack(video_track());
232 }
233 }
234 streams_ = streams;
235 }
236
SetObserver(RtpReceiverObserverInterface * observer)237 void VideoRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
238 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
239 observer_ = observer;
240 // Deliver any notifications the observer may have missed by being set late.
241 if (received_first_packet_ && observer_) {
242 observer_->OnFirstPacketReceived(media_type());
243 }
244 }
245
SetJitterBufferMinimumDelay(absl::optional<double> delay_seconds)246 void VideoRtpReceiver::SetJitterBufferMinimumDelay(
247 absl::optional<double> delay_seconds) {
248 RTC_DCHECK_RUN_ON(worker_thread_);
249 delay_.Set(delay_seconds);
250 if (media_channel_ && ssrc_)
251 media_channel_->SetBaseMinimumPlayoutDelayMs(*ssrc_, delay_.GetMs());
252 }
253
SetMediaChannel(cricket::MediaChannel * media_channel)254 void VideoRtpReceiver::SetMediaChannel(cricket::MediaChannel* media_channel) {
255 RTC_DCHECK_RUN_ON(worker_thread_);
256 RTC_DCHECK(media_channel == nullptr ||
257 media_channel->media_type() == media_type());
258
259 SetMediaChannel_w(media_channel);
260 }
261
SetMediaChannel_w(cricket::MediaChannel * media_channel)262 void VideoRtpReceiver::SetMediaChannel_w(cricket::MediaChannel* media_channel) {
263 RTC_DCHECK_RUN_ON(worker_thread_);
264 if (media_channel == media_channel_)
265 return;
266
267 if (!media_channel) {
268 SetSink(nullptr);
269 }
270
271 bool encoded_sink_enabled = saved_encoded_sink_enabled_;
272 if (encoded_sink_enabled && media_channel_) {
273 // Turn off the old sink, if any.
274 SetEncodedSinkEnabled(false);
275 }
276
277 media_channel_ = static_cast<cricket::VideoMediaChannel*>(media_channel);
278
279 if (media_channel_) {
280 if (saved_generate_keyframe_) {
281 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
282 media_channel_->RequestRecvKeyFrame(ssrc_.value_or(0));
283 saved_generate_keyframe_ = false;
284 }
285 if (encoded_sink_enabled) {
286 SetEncodedSinkEnabled(true);
287 }
288 if (frame_transformer_) {
289 media_channel_->SetDepacketizerToDecoderFrameTransformer(
290 ssrc_.value_or(0), frame_transformer_);
291 }
292 }
293
294 if (!media_channel)
295 source_->ClearCallback();
296 }
297
NotifyFirstPacketReceived()298 void VideoRtpReceiver::NotifyFirstPacketReceived() {
299 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
300 if (observer_) {
301 observer_->OnFirstPacketReceived(media_type());
302 }
303 received_first_packet_ = true;
304 }
305
GetSources() const306 std::vector<RtpSource> VideoRtpReceiver::GetSources() const {
307 RTC_DCHECK_RUN_ON(worker_thread_);
308 if (!ssrc_ || !media_channel_)
309 return std::vector<RtpSource>();
310 return media_channel_->GetSources(*ssrc_);
311 }
312
SetupMediaChannel(absl::optional<uint32_t> ssrc,cricket::MediaChannel * media_channel)313 void VideoRtpReceiver::SetupMediaChannel(absl::optional<uint32_t> ssrc,
314 cricket::MediaChannel* media_channel) {
315 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
316 RTC_DCHECK(media_channel);
317 MediaSourceInterface::SourceState state = source_->state();
318 worker_thread_->BlockingCall([&] {
319 RTC_DCHECK_RUN_ON(worker_thread_);
320 SetMediaChannel_w(media_channel);
321 RestartMediaChannel_w(std::move(ssrc), state);
322 });
323 source_->SetState(MediaSourceInterface::kLive);
324 }
325
OnGenerateKeyFrame()326 void VideoRtpReceiver::OnGenerateKeyFrame() {
327 RTC_DCHECK_RUN_ON(worker_thread_);
328 if (!media_channel_) {
329 RTC_LOG(LS_ERROR)
330 << "VideoRtpReceiver::OnGenerateKeyFrame: No video channel exists.";
331 return;
332 }
333 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
334 media_channel_->RequestRecvKeyFrame(ssrc_.value_or(0));
335 // We need to remember to request generation of a new key frame if the media
336 // channel changes, because there's no feedback whether the keyframe
337 // generation has completed on the channel.
338 saved_generate_keyframe_ = true;
339 }
340
OnEncodedSinkEnabled(bool enable)341 void VideoRtpReceiver::OnEncodedSinkEnabled(bool enable) {
342 RTC_DCHECK_RUN_ON(worker_thread_);
343 SetEncodedSinkEnabled(enable);
344 // Always save the latest state of the callback in case the media_channel_
345 // changes.
346 saved_encoded_sink_enabled_ = enable;
347 }
348
SetEncodedSinkEnabled(bool enable)349 void VideoRtpReceiver::SetEncodedSinkEnabled(bool enable) {
350 RTC_DCHECK_RUN_ON(worker_thread_);
351 if (!media_channel_)
352 return;
353
354 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
355 const auto ssrc = ssrc_.value_or(0);
356
357 if (enable) {
358 media_channel_->SetRecordableEncodedFrameCallback(
359 ssrc, [source = source_](const RecordableEncodedFrame& frame) {
360 source->BroadcastRecordableEncodedFrame(frame);
361 });
362 } else {
363 media_channel_->ClearRecordableEncodedFrameCallback(ssrc);
364 }
365 }
366
367 } // namespace webrtc
368