blob: 7a9ec984faae472e12bf44de487c2c6f04646eec [file] [log] [blame]
Ruslan Burakov501bfba2019-02-11 10:29:19 +01001/*
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#include <utility>
15#include <vector>
16
17#include "api/media_stream_proxy.h"
18#include "api/media_stream_track_proxy.h"
19#include "api/video_track_source_proxy.h"
Ruslan Burakov428dcb22019-04-18 17:49:49 +020020#include "pc/jitter_buffer_delay.h"
21#include "pc/jitter_buffer_delay_proxy.h"
Ruslan Burakov501bfba2019-02-11 10:29:19 +010022#include "pc/media_stream.h"
23#include "pc/video_track.h"
24#include "rtc_base/checks.h"
25#include "rtc_base/location.h"
26#include "rtc_base/logging.h"
27#include "rtc_base/trace_event.h"
28
29namespace webrtc {
30
31VideoRtpReceiver::VideoRtpReceiver(rtc::Thread* worker_thread,
32 std::string receiver_id,
33 std::vector<std::string> stream_ids)
34 : VideoRtpReceiver(worker_thread,
35 receiver_id,
36 CreateStreamsFromIds(std::move(stream_ids))) {}
37
38VideoRtpReceiver::VideoRtpReceiver(
39 rtc::Thread* worker_thread,
40 const std::string& receiver_id,
41 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams)
42 : worker_thread_(worker_thread),
43 id_(receiver_id),
Ruslan Burakov428dcb22019-04-18 17:49:49 +020044 source_(new RefCountedObject<VideoRtpTrackSource>()),
Ruslan Burakov501bfba2019-02-11 10:29:19 +010045 track_(VideoTrackProxy::Create(
46 rtc::Thread::Current(),
47 worker_thread,
48 VideoTrack::Create(
49 receiver_id,
50 VideoTrackSourceProxy::Create(rtc::Thread::Current(),
51 worker_thread,
52 source_),
53 worker_thread))),
Ruslan Burakov428dcb22019-04-18 17:49:49 +020054 attachment_id_(GenerateUniqueId()),
55 delay_(JitterBufferDelayProxy::Create(
56 rtc::Thread::Current(),
57 worker_thread,
58 new rtc::RefCountedObject<JitterBufferDelay>(worker_thread))) {
Ruslan Burakov501bfba2019-02-11 10:29:19 +010059 RTC_DCHECK(worker_thread_);
60 SetStreams(streams);
61 source_->SetState(MediaSourceInterface::kLive);
62}
63
64VideoRtpReceiver::~VideoRtpReceiver() {
65 // Since cricket::VideoRenderer is not reference counted,
66 // we need to remove it from the channel before we are deleted.
67 Stop();
68}
69
70std::vector<std::string> VideoRtpReceiver::stream_ids() const {
71 std::vector<std::string> stream_ids(streams_.size());
72 for (size_t i = 0; i < streams_.size(); ++i)
73 stream_ids[i] = streams_[i]->id();
74 return stream_ids;
75}
76
77bool VideoRtpReceiver::SetSink(rtc::VideoSinkInterface<VideoFrame>* sink) {
78 RTC_DCHECK(media_channel_);
79 RTC_DCHECK(ssrc_);
80 return worker_thread_->Invoke<bool>(
81 RTC_FROM_HERE, [&] { return media_channel_->SetSink(*ssrc_, sink); });
82}
83
84RtpParameters VideoRtpReceiver::GetParameters() const {
85 if (!media_channel_ || !ssrc_ || stopped_) {
86 return RtpParameters();
87 }
88 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
89 return media_channel_->GetRtpReceiveParameters(*ssrc_);
90 });
91}
92
93bool VideoRtpReceiver::SetParameters(const RtpParameters& parameters) {
94 TRACE_EVENT0("webrtc", "VideoRtpReceiver::SetParameters");
95 if (!media_channel_ || !ssrc_ || stopped_) {
96 return false;
97 }
98 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
99 return media_channel_->SetRtpReceiveParameters(*ssrc_, parameters);
100 });
101}
102
103void VideoRtpReceiver::SetFrameDecryptor(
104 rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
105 frame_decryptor_ = std::move(frame_decryptor);
106 // Special Case: Set the frame decryptor to any value on any existing channel.
107 if (media_channel_ && ssrc_.has_value() && !stopped_) {
108 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
109 media_channel_->SetFrameDecryptor(*ssrc_, frame_decryptor_);
110 });
111 }
112}
113
114rtc::scoped_refptr<FrameDecryptorInterface>
115VideoRtpReceiver::GetFrameDecryptor() const {
116 return frame_decryptor_;
117}
118
119void 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_ || !ssrc_) {
126 RTC_LOG(LS_WARNING) << "VideoRtpReceiver::Stop: No video channel exists.";
127 } else {
128 // Allow that SetSink fail. This is the normal case when the underlying
129 // media channel has already been deleted.
130 SetSink(nullptr);
131 }
Ruslan Burakov428dcb22019-04-18 17:49:49 +0200132 delay_->OnStop();
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100133 stopped_ = true;
134}
135
136void VideoRtpReceiver::SetupMediaChannel(uint32_t ssrc) {
137 if (!media_channel_) {
138 RTC_LOG(LS_ERROR)
139 << "VideoRtpReceiver::SetupMediaChannel: No video channel exists.";
140 }
141 if (ssrc_ == ssrc) {
142 return;
143 }
144 if (ssrc_) {
145 SetSink(nullptr);
146 }
147 ssrc_ = ssrc;
148 SetSink(source_->sink());
149 // Attach any existing frame decryptor to the media channel.
150 MaybeAttachFrameDecryptorToMediaChannel(
151 ssrc_, worker_thread_, frame_decryptor_, media_channel_, stopped_);
Ruslan Burakov493a6502019-02-27 15:32:48 +0100152
Ruslan Burakov428dcb22019-04-18 17:49:49 +0200153 delay_->OnStart(media_channel_, ssrc);
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100154}
155
156void VideoRtpReceiver::set_stream_ids(std::vector<std::string> stream_ids) {
157 SetStreams(CreateStreamsFromIds(std::move(stream_ids)));
158}
159
160void VideoRtpReceiver::SetStreams(
161 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
162 // Remove remote track from any streams that are going away.
163 for (const auto& existing_stream : streams_) {
164 bool removed = true;
165 for (const auto& stream : streams) {
166 if (existing_stream->id() == stream->id()) {
167 RTC_DCHECK_EQ(existing_stream.get(), stream.get());
168 removed = false;
169 break;
170 }
171 }
172 if (removed) {
173 existing_stream->RemoveTrack(track_);
174 }
175 }
176 // Add remote track to any streams that are new.
177 for (const auto& stream : streams) {
178 bool added = true;
179 for (const auto& existing_stream : streams_) {
180 if (stream->id() == existing_stream->id()) {
181 RTC_DCHECK_EQ(stream.get(), existing_stream.get());
182 added = false;
183 break;
184 }
185 }
186 if (added) {
187 stream->AddTrack(track_);
188 }
189 }
190 streams_ = streams;
191}
192
193void VideoRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
194 observer_ = observer;
195 // Deliver any notifications the observer may have missed by being set late.
196 if (received_first_packet_ && observer_) {
197 observer_->OnFirstPacketReceived(media_type());
198 }
199}
200
Ruslan Burakov4bac79e2019-04-03 19:55:33 +0200201void VideoRtpReceiver::SetJitterBufferMinimumDelay(
202 absl::optional<double> delay_seconds) {
Ruslan Burakov428dcb22019-04-18 17:49:49 +0200203 delay_->Set(delay_seconds);
Ruslan Burakov4bac79e2019-04-03 19:55:33 +0200204}
205
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100206void VideoRtpReceiver::SetMediaChannel(cricket::MediaChannel* media_channel) {
207 RTC_DCHECK(media_channel == nullptr ||
208 media_channel->media_type() == media_type());
209 media_channel_ = static_cast<cricket::VideoMediaChannel*>(media_channel);
210}
211
212void VideoRtpReceiver::NotifyFirstPacketReceived() {
213 if (observer_) {
214 observer_->OnFirstPacketReceived(media_type());
215 }
216 received_first_packet_ = true;
217}
218
219std::vector<RtpSource> VideoRtpReceiver::GetSources() const {
220 if (!media_channel_ || !ssrc_ || stopped_) {
221 return {};
222 }
223 return worker_thread_->Invoke<std::vector<RtpSource>>(
224 RTC_FROM_HERE, [&] { return media_channel_->GetSources(*ssrc_); });
225}
226
227} // namespace webrtc