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/audio_rtp_receiver.h"
12
13 #include <stddef.h>
14
15 #include <utility>
16 #include <vector>
17
18 #include "api/media_stream_track_proxy.h"
19 #include "api/sequence_checker.h"
20 #include "pc/audio_track.h"
21 #include "pc/jitter_buffer_delay.h"
22 #include "pc/jitter_buffer_delay_proxy.h"
23 #include "rtc_base/checks.h"
24 #include "rtc_base/location.h"
25 #include "rtc_base/logging.h"
26
27 namespace webrtc {
28
AudioRtpReceiver(rtc::Thread * worker_thread,std::string receiver_id,std::vector<std::string> stream_ids,bool is_unified_plan)29 AudioRtpReceiver::AudioRtpReceiver(rtc::Thread* worker_thread,
30 std::string receiver_id,
31 std::vector<std::string> stream_ids,
32 bool is_unified_plan)
33 : AudioRtpReceiver(worker_thread,
34 receiver_id,
35 CreateStreamsFromIds(std::move(stream_ids)),
36 is_unified_plan) {}
37
AudioRtpReceiver(rtc::Thread * worker_thread,const std::string & receiver_id,const std::vector<rtc::scoped_refptr<MediaStreamInterface>> & streams,bool is_unified_plan)38 AudioRtpReceiver::AudioRtpReceiver(
39 rtc::Thread* worker_thread,
40 const std::string& receiver_id,
41 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams,
42 bool is_unified_plan)
43 : worker_thread_(worker_thread),
44 id_(receiver_id),
45 source_(new rtc::RefCountedObject<RemoteAudioSource>(
46 worker_thread,
47 is_unified_plan
48 ? RemoteAudioSource::OnAudioChannelGoneAction::kSurvive
49 : RemoteAudioSource::OnAudioChannelGoneAction::kEnd)),
50 track_(AudioTrackProxyWithInternal<AudioTrack>::Create(
51 rtc::Thread::Current(),
52 AudioTrack::Create(receiver_id, source_))),
53 cached_track_enabled_(track_->enabled()),
54 attachment_id_(GenerateUniqueId()),
55 delay_(JitterBufferDelayProxy::Create(
56 rtc::Thread::Current(),
57 worker_thread_,
58 new rtc::RefCountedObject<JitterBufferDelay>(worker_thread))) {
59 RTC_DCHECK(worker_thread_);
60 RTC_DCHECK(track_->GetSource()->remote());
61 track_->RegisterObserver(this);
62 track_->GetSource()->RegisterAudioObserver(this);
63 SetStreams(streams);
64 }
65
~AudioRtpReceiver()66 AudioRtpReceiver::~AudioRtpReceiver() {
67 track_->GetSource()->UnregisterAudioObserver(this);
68 track_->UnregisterObserver(this);
69 Stop();
70 }
71
OnChanged()72 void AudioRtpReceiver::OnChanged() {
73 if (cached_track_enabled_ != track_->enabled()) {
74 cached_track_enabled_ = track_->enabled();
75 Reconfigure();
76 }
77 }
78
SetOutputVolume(double volume)79 bool AudioRtpReceiver::SetOutputVolume(double volume) {
80 RTC_DCHECK_GE(volume, 0.0);
81 RTC_DCHECK_LE(volume, 10.0);
82 RTC_DCHECK(media_channel_);
83 RTC_DCHECK(!stopped_);
84 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
85 return ssrc_ ? media_channel_->SetOutputVolume(*ssrc_, volume)
86 : media_channel_->SetDefaultOutputVolume(volume);
87 });
88 }
89
OnSetVolume(double volume)90 void AudioRtpReceiver::OnSetVolume(double volume) {
91 RTC_DCHECK_GE(volume, 0);
92 RTC_DCHECK_LE(volume, 10);
93 cached_volume_ = volume;
94 if (!media_channel_ || stopped_) {
95 RTC_LOG(LS_ERROR)
96 << "AudioRtpReceiver::OnSetVolume: No audio channel exists.";
97 return;
98 }
99 // When the track is disabled, the volume of the source, which is the
100 // corresponding WebRtc Voice Engine channel will be 0. So we do not allow
101 // setting the volume to the source when the track is disabled.
102 if (!stopped_ && track_->enabled()) {
103 if (!SetOutputVolume(cached_volume_)) {
104 RTC_NOTREACHED();
105 }
106 }
107 }
108
stream_ids() const109 std::vector<std::string> AudioRtpReceiver::stream_ids() const {
110 std::vector<std::string> stream_ids(streams_.size());
111 for (size_t i = 0; i < streams_.size(); ++i)
112 stream_ids[i] = streams_[i]->id();
113 return stream_ids;
114 }
115
GetParameters() const116 RtpParameters AudioRtpReceiver::GetParameters() const {
117 if (!media_channel_ || stopped_) {
118 return RtpParameters();
119 }
120 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
121 return ssrc_ ? media_channel_->GetRtpReceiveParameters(*ssrc_)
122 : media_channel_->GetDefaultRtpReceiveParameters();
123 });
124 }
125
SetFrameDecryptor(rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor)126 void AudioRtpReceiver::SetFrameDecryptor(
127 rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
128 frame_decryptor_ = std::move(frame_decryptor);
129 // Special Case: Set the frame decryptor to any value on any existing channel.
130 if (media_channel_ && ssrc_.has_value() && !stopped_) {
131 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
132 media_channel_->SetFrameDecryptor(*ssrc_, frame_decryptor_);
133 });
134 }
135 }
136
137 rtc::scoped_refptr<FrameDecryptorInterface>
GetFrameDecryptor() const138 AudioRtpReceiver::GetFrameDecryptor() const {
139 return frame_decryptor_;
140 }
141
Stop()142 void AudioRtpReceiver::Stop() {
143 // TODO(deadbeef): Need to do more here to fully stop receiving packets.
144 if (stopped_) {
145 return;
146 }
147 source_->SetState(MediaSourceInterface::kEnded);
148 if (media_channel_) {
149 // Allow that SetOutputVolume fail. This is the normal case when the
150 // underlying media channel has already been deleted.
151 SetOutputVolume(0.0);
152 }
153 stopped_ = true;
154 }
155
StopAndEndTrack()156 void AudioRtpReceiver::StopAndEndTrack() {
157 Stop();
158 track_->internal()->set_ended();
159 }
160
RestartMediaChannel(absl::optional<uint32_t> ssrc)161 void AudioRtpReceiver::RestartMediaChannel(absl::optional<uint32_t> ssrc) {
162 RTC_DCHECK(media_channel_);
163 if (!stopped_ && ssrc_ == ssrc) {
164 return;
165 }
166
167 if (!stopped_) {
168 source_->Stop(media_channel_, ssrc_);
169 delay_->OnStop();
170 }
171 ssrc_ = ssrc;
172 stopped_ = false;
173 source_->Start(media_channel_, ssrc);
174 delay_->OnStart(media_channel_, ssrc.value_or(0));
175 Reconfigure();
176 }
177
SetupMediaChannel(uint32_t ssrc)178 void AudioRtpReceiver::SetupMediaChannel(uint32_t ssrc) {
179 if (!media_channel_) {
180 RTC_LOG(LS_ERROR)
181 << "AudioRtpReceiver::SetupMediaChannel: No audio channel exists.";
182 return;
183 }
184 RestartMediaChannel(ssrc);
185 }
186
SetupUnsignaledMediaChannel()187 void AudioRtpReceiver::SetupUnsignaledMediaChannel() {
188 if (!media_channel_) {
189 RTC_LOG(LS_ERROR) << "AudioRtpReceiver::SetupUnsignaledMediaChannel: No "
190 "audio channel exists.";
191 }
192 RestartMediaChannel(absl::nullopt);
193 }
194
set_stream_ids(std::vector<std::string> stream_ids)195 void AudioRtpReceiver::set_stream_ids(std::vector<std::string> stream_ids) {
196 SetStreams(CreateStreamsFromIds(std::move(stream_ids)));
197 }
198
SetStreams(const std::vector<rtc::scoped_refptr<MediaStreamInterface>> & streams)199 void AudioRtpReceiver::SetStreams(
200 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
201 // Remove remote track from any streams that are going away.
202 for (const auto& existing_stream : streams_) {
203 bool removed = true;
204 for (const auto& stream : streams) {
205 if (existing_stream->id() == stream->id()) {
206 RTC_DCHECK_EQ(existing_stream.get(), stream.get());
207 removed = false;
208 break;
209 }
210 }
211 if (removed) {
212 existing_stream->RemoveTrack(track_);
213 }
214 }
215 // Add remote track to any streams that are new.
216 for (const auto& stream : streams) {
217 bool added = true;
218 for (const auto& existing_stream : streams_) {
219 if (stream->id() == existing_stream->id()) {
220 RTC_DCHECK_EQ(stream.get(), existing_stream.get());
221 added = false;
222 break;
223 }
224 }
225 if (added) {
226 stream->AddTrack(track_);
227 }
228 }
229 streams_ = streams;
230 }
231
GetSources() const232 std::vector<RtpSource> AudioRtpReceiver::GetSources() const {
233 if (!media_channel_ || !ssrc_ || stopped_) {
234 return {};
235 }
236 return worker_thread_->Invoke<std::vector<RtpSource>>(
237 RTC_FROM_HERE, [&] { return media_channel_->GetSources(*ssrc_); });
238 }
239
SetDepacketizerToDecoderFrameTransformer(rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer)240 void AudioRtpReceiver::SetDepacketizerToDecoderFrameTransformer(
241 rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer) {
242 worker_thread_->Invoke<void>(
243 RTC_FROM_HERE, [this, frame_transformer = std::move(frame_transformer)] {
244 RTC_DCHECK_RUN_ON(worker_thread_);
245 frame_transformer_ = frame_transformer;
246 if (media_channel_ && ssrc_.has_value() && !stopped_) {
247 media_channel_->SetDepacketizerToDecoderFrameTransformer(
248 *ssrc_, frame_transformer);
249 }
250 });
251 }
252
Reconfigure()253 void AudioRtpReceiver::Reconfigure() {
254 if (!media_channel_ || stopped_) {
255 RTC_LOG(LS_ERROR)
256 << "AudioRtpReceiver::Reconfigure: No audio channel exists.";
257 return;
258 }
259 if (!SetOutputVolume(track_->enabled() ? cached_volume_ : 0)) {
260 RTC_NOTREACHED();
261 }
262 // Reattach the frame decryptor if we were reconfigured.
263 MaybeAttachFrameDecryptorToMediaChannel(
264 ssrc_, worker_thread_, frame_decryptor_, media_channel_, stopped_);
265
266 if (media_channel_ && ssrc_.has_value() && !stopped_) {
267 worker_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
268 RTC_DCHECK_RUN_ON(worker_thread_);
269 if (!frame_transformer_)
270 return;
271 media_channel_->SetDepacketizerToDecoderFrameTransformer(
272 *ssrc_, frame_transformer_);
273 });
274 }
275 }
276
SetObserver(RtpReceiverObserverInterface * observer)277 void AudioRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
278 observer_ = observer;
279 // Deliver any notifications the observer may have missed by being set late.
280 if (received_first_packet_ && observer_) {
281 observer_->OnFirstPacketReceived(media_type());
282 }
283 }
284
SetJitterBufferMinimumDelay(absl::optional<double> delay_seconds)285 void AudioRtpReceiver::SetJitterBufferMinimumDelay(
286 absl::optional<double> delay_seconds) {
287 delay_->Set(delay_seconds);
288 }
289
SetMediaChannel(cricket::MediaChannel * media_channel)290 void AudioRtpReceiver::SetMediaChannel(cricket::MediaChannel* media_channel) {
291 RTC_DCHECK(media_channel == nullptr ||
292 media_channel->media_type() == media_type());
293 media_channel_ = static_cast<cricket::VoiceMediaChannel*>(media_channel);
294 }
295
NotifyFirstPacketReceived()296 void AudioRtpReceiver::NotifyFirstPacketReceived() {
297 if (observer_) {
298 observer_->OnFirstPacketReceived(media_type());
299 }
300 received_first_packet_ = true;
301 }
302
303 } // namespace webrtc
304