• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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