blob: 2d9a23fb0f677c6a51c6e599217c8a6ea54814d5 [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"
20#include "pc/media_stream.h"
21#include "pc/video_track.h"
22#include "rtc_base/checks.h"
23#include "rtc_base/location.h"
24#include "rtc_base/logging.h"
25#include "rtc_base/trace_event.h"
26
27namespace webrtc {
28
29VideoRtpReceiver::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
36VideoRtpReceiver::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>()),
43 track_(VideoTrackProxy::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 RTC_DCHECK(worker_thread_);
54 SetStreams(streams);
55 source_->SetState(MediaSourceInterface::kLive);
56}
57
58VideoRtpReceiver::~VideoRtpReceiver() {
59 // Since cricket::VideoRenderer is not reference counted,
60 // we need to remove it from the channel before we are deleted.
61 Stop();
62}
63
64std::vector<std::string> VideoRtpReceiver::stream_ids() const {
65 std::vector<std::string> stream_ids(streams_.size());
66 for (size_t i = 0; i < streams_.size(); ++i)
67 stream_ids[i] = streams_[i]->id();
68 return stream_ids;
69}
70
71bool VideoRtpReceiver::SetSink(rtc::VideoSinkInterface<VideoFrame>* sink) {
72 RTC_DCHECK(media_channel_);
73 RTC_DCHECK(ssrc_);
74 return worker_thread_->Invoke<bool>(
75 RTC_FROM_HERE, [&] { return media_channel_->SetSink(*ssrc_, sink); });
76}
77
78RtpParameters VideoRtpReceiver::GetParameters() const {
79 if (!media_channel_ || !ssrc_ || stopped_) {
80 return RtpParameters();
81 }
82 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
83 return media_channel_->GetRtpReceiveParameters(*ssrc_);
84 });
85}
86
87bool VideoRtpReceiver::SetParameters(const RtpParameters& parameters) {
88 TRACE_EVENT0("webrtc", "VideoRtpReceiver::SetParameters");
89 if (!media_channel_ || !ssrc_ || stopped_) {
90 return false;
91 }
92 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
93 return media_channel_->SetRtpReceiveParameters(*ssrc_, parameters);
94 });
95}
96
97void VideoRtpReceiver::SetFrameDecryptor(
98 rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
99 frame_decryptor_ = std::move(frame_decryptor);
100 // Special Case: Set the frame decryptor to any value on any existing channel.
101 if (media_channel_ && ssrc_.has_value() && !stopped_) {
102 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
103 media_channel_->SetFrameDecryptor(*ssrc_, frame_decryptor_);
104 });
105 }
106}
107
108rtc::scoped_refptr<FrameDecryptorInterface>
109VideoRtpReceiver::GetFrameDecryptor() const {
110 return frame_decryptor_;
111}
112
113void VideoRtpReceiver::Stop() {
114 // TODO(deadbeef): Need to do more here to fully stop receiving packets.
115 if (stopped_) {
116 return;
117 }
118 source_->SetState(MediaSourceInterface::kEnded);
119 if (!media_channel_ || !ssrc_) {
120 RTC_LOG(LS_WARNING) << "VideoRtpReceiver::Stop: No video channel exists.";
121 } else {
122 // Allow that SetSink fail. This is the normal case when the underlying
123 // media channel has already been deleted.
124 SetSink(nullptr);
125 }
126 stopped_ = true;
127}
128
129void VideoRtpReceiver::SetupMediaChannel(uint32_t ssrc) {
130 if (!media_channel_) {
131 RTC_LOG(LS_ERROR)
132 << "VideoRtpReceiver::SetupMediaChannel: No video channel exists.";
133 }
134 if (ssrc_ == ssrc) {
135 return;
136 }
137 if (ssrc_) {
138 SetSink(nullptr);
139 }
140 ssrc_ = ssrc;
141 SetSink(source_->sink());
142 // Attach any existing frame decryptor to the media channel.
143 MaybeAttachFrameDecryptorToMediaChannel(
144 ssrc_, worker_thread_, frame_decryptor_, media_channel_, stopped_);
145}
146
147void VideoRtpReceiver::set_stream_ids(std::vector<std::string> stream_ids) {
148 SetStreams(CreateStreamsFromIds(std::move(stream_ids)));
149}
150
151void VideoRtpReceiver::SetStreams(
152 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
153 // Remove remote track from any streams that are going away.
154 for (const auto& existing_stream : streams_) {
155 bool removed = true;
156 for (const auto& stream : streams) {
157 if (existing_stream->id() == stream->id()) {
158 RTC_DCHECK_EQ(existing_stream.get(), stream.get());
159 removed = false;
160 break;
161 }
162 }
163 if (removed) {
164 existing_stream->RemoveTrack(track_);
165 }
166 }
167 // Add remote track to any streams that are new.
168 for (const auto& stream : streams) {
169 bool added = true;
170 for (const auto& existing_stream : streams_) {
171 if (stream->id() == existing_stream->id()) {
172 RTC_DCHECK_EQ(stream.get(), existing_stream.get());
173 added = false;
174 break;
175 }
176 }
177 if (added) {
178 stream->AddTrack(track_);
179 }
180 }
181 streams_ = streams;
182}
183
184void VideoRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
185 observer_ = observer;
186 // Deliver any notifications the observer may have missed by being set late.
187 if (received_first_packet_ && observer_) {
188 observer_->OnFirstPacketReceived(media_type());
189 }
190}
191
192void VideoRtpReceiver::SetMediaChannel(cricket::MediaChannel* media_channel) {
193 RTC_DCHECK(media_channel == nullptr ||
194 media_channel->media_type() == media_type());
195 media_channel_ = static_cast<cricket::VideoMediaChannel*>(media_channel);
196}
197
198void VideoRtpReceiver::NotifyFirstPacketReceived() {
199 if (observer_) {
200 observer_->OnFirstPacketReceived(media_type());
201 }
202 received_first_packet_ = true;
203}
204
205std::vector<RtpSource> VideoRtpReceiver::GetSources() const {
206 if (!media_channel_ || !ssrc_ || stopped_) {
207 return {};
208 }
209 return worker_thread_->Invoke<std::vector<RtpSource>>(
210 RTC_FROM_HERE, [&] { return media_channel_->GetSources(*ssrc_); });
211}
212
213} // namespace webrtc