xref: /aosp_15_r20/external/webrtc/pc/video_rtp_receiver.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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