blob: d9d2a2e810549e56809bf52bfa0a7923af80fca4 [file] [log] [blame]
Ruslan Burakov501bfba2019-02-11 09:29:191/*
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>
Jonas Olssona4d87372019-07-05 17:08:3314
Ruslan Burakov501bfba2019-02-11 09:29:1915#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"
Ruslan Burakov428dcb22019-04-18 15:49:4921#include "pc/jitter_buffer_delay.h"
22#include "pc/jitter_buffer_delay_proxy.h"
Ruslan Burakov501bfba2019-02-11 09:29:1923#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
30namespace webrtc {
31
32VideoRtpReceiver::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
39VideoRtpReceiver::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),
Markus Handelld5e2f212019-11-26 08:30:0845 source_(new RefCountedObject<VideoRtpTrackSource>(this)),
Ruslan Burakov501bfba2019-02-11 09:29:1946 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))),
Ruslan Burakov428dcb22019-04-18 15:49:4955 attachment_id_(GenerateUniqueId()),
56 delay_(JitterBufferDelayProxy::Create(
57 rtc::Thread::Current(),
58 worker_thread,
59 new rtc::RefCountedObject<JitterBufferDelay>(worker_thread))) {
Ruslan Burakov501bfba2019-02-11 09:29:1960 RTC_DCHECK(worker_thread_);
61 SetStreams(streams);
62 source_->SetState(MediaSourceInterface::kLive);
63}
64
65VideoRtpReceiver::~VideoRtpReceiver() {
66 // Since cricket::VideoRenderer is not reference counted,
67 // we need to remove it from the channel before we are deleted.
68 Stop();
Markus Handelld5e2f212019-11-26 08:30:0869 // Make sure we can't be called by the |source_| anymore.
70 worker_thread_->Invoke<void>(RTC_FROM_HERE,
71 [this] { source_->ClearCallback(); });
Ruslan Burakov501bfba2019-02-11 09:29:1972}
73
74std::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
81bool VideoRtpReceiver::SetSink(rtc::VideoSinkInterface<VideoFrame>* sink) {
82 RTC_DCHECK(media_channel_);
Saurav Das7262fc22019-09-11 23:23:0583 RTC_DCHECK(!stopped_);
84 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
85 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
86 return media_channel_->SetSink(ssrc_.value_or(0), sink);
87 });
Ruslan Burakov501bfba2019-02-11 09:29:1988}
89
90RtpParameters VideoRtpReceiver::GetParameters() const {
Saurav Das7262fc22019-09-11 23:23:0591 if (!media_channel_ || stopped_) {
Ruslan Burakov501bfba2019-02-11 09:29:1992 return RtpParameters();
93 }
94 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
Saurav Das7262fc22019-09-11 23:23:0595 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
96 return media_channel_->GetRtpReceiveParameters(ssrc_.value_or(0));
Ruslan Burakov501bfba2019-02-11 09:29:1997 });
98}
99
100bool VideoRtpReceiver::SetParameters(const RtpParameters& parameters) {
101 TRACE_EVENT0("webrtc", "VideoRtpReceiver::SetParameters");
Saurav Das7262fc22019-09-11 23:23:05102 if (!media_channel_ || stopped_) {
Ruslan Burakov501bfba2019-02-11 09:29:19103 return false;
104 }
105 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
Saurav Das7262fc22019-09-11 23:23:05106 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
107 return media_channel_->SetRtpReceiveParameters(ssrc_.value_or(0),
108 parameters);
Ruslan Burakov501bfba2019-02-11 09:29:19109 });
110}
111
112void VideoRtpReceiver::SetFrameDecryptor(
113 rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
114 frame_decryptor_ = std::move(frame_decryptor);
115 // Special Case: Set the frame decryptor to any value on any existing channel.
116 if (media_channel_ && ssrc_.has_value() && !stopped_) {
117 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
118 media_channel_->SetFrameDecryptor(*ssrc_, frame_decryptor_);
119 });
120 }
121}
122
123rtc::scoped_refptr<FrameDecryptorInterface>
124VideoRtpReceiver::GetFrameDecryptor() const {
125 return frame_decryptor_;
126}
127
128void VideoRtpReceiver::Stop() {
129 // TODO(deadbeef): Need to do more here to fully stop receiving packets.
130 if (stopped_) {
131 return;
132 }
133 source_->SetState(MediaSourceInterface::kEnded);
Saurav Das7262fc22019-09-11 23:23:05134 if (!media_channel_) {
Ruslan Burakov501bfba2019-02-11 09:29:19135 RTC_LOG(LS_WARNING) << "VideoRtpReceiver::Stop: No video channel exists.";
136 } else {
137 // Allow that SetSink fail. This is the normal case when the underlying
138 // media channel has already been deleted.
139 SetSink(nullptr);
140 }
Ruslan Burakov428dcb22019-04-18 15:49:49141 delay_->OnStop();
Ruslan Burakov501bfba2019-02-11 09:29:19142 stopped_ = true;
143}
144
Saurav Das7262fc22019-09-11 23:23:05145void VideoRtpReceiver::RestartMediaChannel(absl::optional<uint32_t> ssrc) {
146 RTC_DCHECK(media_channel_);
147 if (!stopped_ && ssrc_ == ssrc) {
148 return;
149 }
150 if (!stopped_) {
151 SetSink(nullptr);
152 }
153 stopped_ = false;
154 ssrc_ = ssrc;
155 SetSink(source_->sink());
156
157 // Attach any existing frame decryptor to the media channel.
158 MaybeAttachFrameDecryptorToMediaChannel(
159 ssrc, worker_thread_, frame_decryptor_, media_channel_, stopped_);
160 // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
161 // value.
162 delay_->OnStart(media_channel_, ssrc.value_or(0));
163}
164
Ruslan Burakov501bfba2019-02-11 09:29:19165void VideoRtpReceiver::SetupMediaChannel(uint32_t ssrc) {
166 if (!media_channel_) {
167 RTC_LOG(LS_ERROR)
168 << "VideoRtpReceiver::SetupMediaChannel: No video channel exists.";
169 }
Saurav Das7262fc22019-09-11 23:23:05170 RestartMediaChannel(ssrc);
171}
Ruslan Burakov493a6502019-02-27 14:32:48172
Saurav Das7262fc22019-09-11 23:23:05173void VideoRtpReceiver::SetupUnsignaledMediaChannel() {
174 if (!media_channel_) {
175 RTC_LOG(LS_ERROR) << "VideoRtpReceiver::SetupUnsignaledMediaChannel: No "
176 "video channel exists.";
177 }
178 RestartMediaChannel(absl::nullopt);
Ruslan Burakov501bfba2019-02-11 09:29:19179}
180
181void VideoRtpReceiver::set_stream_ids(std::vector<std::string> stream_ids) {
182 SetStreams(CreateStreamsFromIds(std::move(stream_ids)));
183}
184
185void VideoRtpReceiver::SetStreams(
186 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
187 // Remove remote track from any streams that are going away.
188 for (const auto& existing_stream : streams_) {
189 bool removed = true;
190 for (const auto& stream : streams) {
191 if (existing_stream->id() == stream->id()) {
192 RTC_DCHECK_EQ(existing_stream.get(), stream.get());
193 removed = false;
194 break;
195 }
196 }
197 if (removed) {
198 existing_stream->RemoveTrack(track_);
199 }
200 }
201 // Add remote track to any streams that are new.
202 for (const auto& stream : streams) {
203 bool added = true;
204 for (const auto& existing_stream : streams_) {
205 if (stream->id() == existing_stream->id()) {
206 RTC_DCHECK_EQ(stream.get(), existing_stream.get());
207 added = false;
208 break;
209 }
210 }
211 if (added) {
212 stream->AddTrack(track_);
213 }
214 }
215 streams_ = streams;
216}
217
218void VideoRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
219 observer_ = observer;
220 // Deliver any notifications the observer may have missed by being set late.
221 if (received_first_packet_ && observer_) {
222 observer_->OnFirstPacketReceived(media_type());
223 }
224}
225
Ruslan Burakov4bac79e2019-04-03 17:55:33226void VideoRtpReceiver::SetJitterBufferMinimumDelay(
227 absl::optional<double> delay_seconds) {
Ruslan Burakov428dcb22019-04-18 15:49:49228 delay_->Set(delay_seconds);
Ruslan Burakov4bac79e2019-04-03 17:55:33229}
230
Ruslan Burakov501bfba2019-02-11 09:29:19231void VideoRtpReceiver::SetMediaChannel(cricket::MediaChannel* media_channel) {
232 RTC_DCHECK(media_channel == nullptr ||
233 media_channel->media_type() == media_type());
234 media_channel_ = static_cast<cricket::VideoMediaChannel*>(media_channel);
235}
236
237void VideoRtpReceiver::NotifyFirstPacketReceived() {
238 if (observer_) {
239 observer_->OnFirstPacketReceived(media_type());
240 }
241 received_first_packet_ = true;
242}
243
244std::vector<RtpSource> VideoRtpReceiver::GetSources() const {
245 if (!media_channel_ || !ssrc_ || stopped_) {
246 return {};
247 }
248 return worker_thread_->Invoke<std::vector<RtpSource>>(
249 RTC_FROM_HERE, [&] { return media_channel_->GetSources(*ssrc_); });
250}
251
Markus Handelld5e2f212019-11-26 08:30:08252void VideoRtpReceiver::OnGenerateKeyFrame() {
253 RTC_DCHECK_RUN_ON(worker_thread_);
254}
255
256void VideoRtpReceiver::OnEncodedSinkEnabled(bool enable) {
257 RTC_DCHECK_RUN_ON(worker_thread_);
258}
259
Ruslan Burakov501bfba2019-02-11 09:29:19260} // namespace webrtc