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