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