blob: e8fad28d1096ba9c0f3eba8c6467bec76fd48d1b [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/audio_rtp_receiver.h"
12
13#include <stddef.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020014
Ruslan Burakov501bfba2019-02-11 10:29:19 +010015#include <utility>
16#include <vector>
17
Ruslan Burakov501bfba2019-02-11 10:29:19 +010018#include "api/media_stream_track_proxy.h"
Artem Titovd15a5752021-02-10 14:31:24 +010019#include "api/sequence_checker.h"
Ruslan Burakov501bfba2019-02-11 10:29:19 +010020#include "pc/audio_track.h"
Ruslan Burakov428dcb22019-04-18 17:49:49 +020021#include "pc/jitter_buffer_delay.h"
22#include "pc/jitter_buffer_delay_proxy.h"
Ruslan Burakov501bfba2019-02-11 10:29:19 +010023#include "rtc_base/checks.h"
24#include "rtc_base/location.h"
25#include "rtc_base/logging.h"
Ruslan Burakov501bfba2019-02-11 10:29:19 +010026
27namespace webrtc {
28
29AudioRtpReceiver::AudioRtpReceiver(rtc::Thread* worker_thread,
30 std::string receiver_id,
31 std::vector<std::string> stream_ids)
32 : AudioRtpReceiver(worker_thread,
33 receiver_id,
34 CreateStreamsFromIds(std::move(stream_ids))) {}
35
36AudioRtpReceiver::AudioRtpReceiver(
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 rtc::RefCountedObject<RemoteAudioSource>(worker_thread)),
Harald Alvestrand1ee33252020-09-24 13:31:15 +000043 track_(AudioTrackProxyWithInternal<AudioTrack>::Create(
44 rtc::Thread::Current(),
45 AudioTrack::Create(receiver_id, source_))),
Ruslan Burakov501bfba2019-02-11 10:29:19 +010046 cached_track_enabled_(track_->enabled()),
Ruslan Burakov428dcb22019-04-18 17:49:49 +020047 attachment_id_(GenerateUniqueId()),
48 delay_(JitterBufferDelayProxy::Create(
49 rtc::Thread::Current(),
50 worker_thread_,
51 new rtc::RefCountedObject<JitterBufferDelay>(worker_thread))) {
Ruslan Burakov501bfba2019-02-11 10:29:19 +010052 RTC_DCHECK(worker_thread_);
53 RTC_DCHECK(track_->GetSource()->remote());
54 track_->RegisterObserver(this);
55 track_->GetSource()->RegisterAudioObserver(this);
56 SetStreams(streams);
57}
58
59AudioRtpReceiver::~AudioRtpReceiver() {
60 track_->GetSource()->UnregisterAudioObserver(this);
61 track_->UnregisterObserver(this);
62 Stop();
63}
64
65void AudioRtpReceiver::OnChanged() {
66 if (cached_track_enabled_ != track_->enabled()) {
67 cached_track_enabled_ = track_->enabled();
68 Reconfigure();
69 }
70}
71
72bool AudioRtpReceiver::SetOutputVolume(double volume) {
73 RTC_DCHECK_GE(volume, 0.0);
74 RTC_DCHECK_LE(volume, 10.0);
75 RTC_DCHECK(media_channel_);
Saurav Das7262fc22019-09-11 16:23:05 -070076 RTC_DCHECK(!stopped_);
Ruslan Burakov501bfba2019-02-11 10:29:19 +010077 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
Saurav Das749f6602019-12-04 09:31:36 -080078 return ssrc_ ? media_channel_->SetOutputVolume(*ssrc_, volume)
79 : media_channel_->SetDefaultOutputVolume(volume);
Ruslan Burakov501bfba2019-02-11 10:29:19 +010080 });
81}
82
83void AudioRtpReceiver::OnSetVolume(double volume) {
84 RTC_DCHECK_GE(volume, 0);
85 RTC_DCHECK_LE(volume, 10);
86 cached_volume_ = volume;
Saurav Das7262fc22019-09-11 16:23:05 -070087 if (!media_channel_ || stopped_) {
Ruslan Burakov501bfba2019-02-11 10:29:19 +010088 RTC_LOG(LS_ERROR)
89 << "AudioRtpReceiver::OnSetVolume: No audio channel exists.";
90 return;
91 }
92 // When the track is disabled, the volume of the source, which is the
93 // corresponding WebRtc Voice Engine channel will be 0. So we do not allow
94 // setting the volume to the source when the track is disabled.
95 if (!stopped_ && track_->enabled()) {
96 if (!SetOutputVolume(cached_volume_)) {
97 RTC_NOTREACHED();
98 }
99 }
100}
101
102std::vector<std::string> AudioRtpReceiver::stream_ids() const {
103 std::vector<std::string> stream_ids(streams_.size());
104 for (size_t i = 0; i < streams_.size(); ++i)
105 stream_ids[i] = streams_[i]->id();
106 return stream_ids;
107}
108
109RtpParameters AudioRtpReceiver::GetParameters() const {
Saurav Das7262fc22019-09-11 16:23:05 -0700110 if (!media_channel_ || stopped_) {
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100111 return RtpParameters();
112 }
113 return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
Saurav Das749f6602019-12-04 09:31:36 -0800114 return ssrc_ ? media_channel_->GetRtpReceiveParameters(*ssrc_)
115 : media_channel_->GetDefaultRtpReceiveParameters();
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100116 });
117}
118
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100119void AudioRtpReceiver::SetFrameDecryptor(
120 rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
121 frame_decryptor_ = std::move(frame_decryptor);
122 // Special Case: Set the frame decryptor to any value on any existing channel.
123 if (media_channel_ && ssrc_.has_value() && !stopped_) {
124 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
125 media_channel_->SetFrameDecryptor(*ssrc_, frame_decryptor_);
126 });
127 }
128}
129
130rtc::scoped_refptr<FrameDecryptorInterface>
131AudioRtpReceiver::GetFrameDecryptor() const {
132 return frame_decryptor_;
133}
134
135void AudioRtpReceiver::Stop() {
136 // TODO(deadbeef): Need to do more here to fully stop receiving packets.
137 if (stopped_) {
138 return;
139 }
Saurav Das7262fc22019-09-11 16:23:05 -0700140 if (media_channel_) {
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100141 // Allow that SetOutputVolume fail. This is the normal case when the
142 // underlying media channel has already been deleted.
143 SetOutputVolume(0.0);
144 }
145 stopped_ = true;
146}
147
Harald Alvestrand1ee33252020-09-24 13:31:15 +0000148void AudioRtpReceiver::StopAndEndTrack() {
149 Stop();
150 track_->internal()->set_ended();
151}
152
Saurav Das7262fc22019-09-11 16:23:05 -0700153void AudioRtpReceiver::RestartMediaChannel(absl::optional<uint32_t> ssrc) {
154 RTC_DCHECK(media_channel_);
155 if (!stopped_ && ssrc_ == ssrc) {
156 return;
157 }
158
159 if (!stopped_) {
Saurav Das749f6602019-12-04 09:31:36 -0800160 source_->Stop(media_channel_, ssrc_);
Saurav Das7262fc22019-09-11 16:23:05 -0700161 delay_->OnStop();
162 }
163 ssrc_ = ssrc;
164 stopped_ = false;
Saurav Das749f6602019-12-04 09:31:36 -0800165 source_->Start(media_channel_, ssrc);
Saurav Das7262fc22019-09-11 16:23:05 -0700166 delay_->OnStart(media_channel_, ssrc.value_or(0));
167 Reconfigure();
168}
169
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100170void AudioRtpReceiver::SetupMediaChannel(uint32_t ssrc) {
171 if (!media_channel_) {
172 RTC_LOG(LS_ERROR)
173 << "AudioRtpReceiver::SetupMediaChannel: No audio channel exists.";
174 return;
175 }
Saurav Das7262fc22019-09-11 16:23:05 -0700176 RestartMediaChannel(ssrc);
177}
178
179void AudioRtpReceiver::SetupUnsignaledMediaChannel() {
180 if (!media_channel_) {
181 RTC_LOG(LS_ERROR) << "AudioRtpReceiver::SetupUnsignaledMediaChannel: No "
182 "audio channel exists.";
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100183 }
Saurav Das7262fc22019-09-11 16:23:05 -0700184 RestartMediaChannel(absl::nullopt);
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100185}
186
187void AudioRtpReceiver::set_stream_ids(std::vector<std::string> stream_ids) {
188 SetStreams(CreateStreamsFromIds(std::move(stream_ids)));
189}
190
191void AudioRtpReceiver::SetStreams(
192 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
193 // Remove remote track from any streams that are going away.
194 for (const auto& existing_stream : streams_) {
195 bool removed = true;
196 for (const auto& stream : streams) {
197 if (existing_stream->id() == stream->id()) {
198 RTC_DCHECK_EQ(existing_stream.get(), stream.get());
199 removed = false;
200 break;
201 }
202 }
203 if (removed) {
204 existing_stream->RemoveTrack(track_);
205 }
206 }
207 // Add remote track to any streams that are new.
208 for (const auto& stream : streams) {
209 bool added = true;
210 for (const auto& existing_stream : streams_) {
211 if (stream->id() == existing_stream->id()) {
212 RTC_DCHECK_EQ(stream.get(), existing_stream.get());
213 added = false;
214 break;
215 }
216 }
217 if (added) {
218 stream->AddTrack(track_);
219 }
220 }
221 streams_ = streams;
222}
223
224std::vector<RtpSource> AudioRtpReceiver::GetSources() const {
225 if (!media_channel_ || !ssrc_ || stopped_) {
226 return {};
227 }
228 return worker_thread_->Invoke<std::vector<RtpSource>>(
229 RTC_FROM_HERE, [&] { return media_channel_->GetSources(*ssrc_); });
230}
231
Marina Ciocea3e9af7f2020-04-01 07:46:16 +0200232void AudioRtpReceiver::SetDepacketizerToDecoderFrameTransformer(
233 rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer) {
Marina Ciocea55c991c2020-04-02 15:01:25 +0200234 worker_thread_->Invoke<void>(
235 RTC_FROM_HERE, [this, frame_transformer = std::move(frame_transformer)] {
236 RTC_DCHECK_RUN_ON(worker_thread_);
237 frame_transformer_ = frame_transformer;
238 if (media_channel_ && ssrc_.has_value() && !stopped_) {
Marina Ciocea3e9af7f2020-04-01 07:46:16 +0200239 media_channel_->SetDepacketizerToDecoderFrameTransformer(
240 *ssrc_, frame_transformer);
Marina Ciocea55c991c2020-04-02 15:01:25 +0200241 }
242 });
Marina Ciocea3e9af7f2020-04-01 07:46:16 +0200243}
244
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100245void AudioRtpReceiver::Reconfigure() {
Saurav Das7262fc22019-09-11 16:23:05 -0700246 if (!media_channel_ || stopped_) {
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100247 RTC_LOG(LS_ERROR)
248 << "AudioRtpReceiver::Reconfigure: No audio channel exists.";
249 return;
250 }
251 if (!SetOutputVolume(track_->enabled() ? cached_volume_ : 0)) {
252 RTC_NOTREACHED();
253 }
254 // Reattach the frame decryptor if we were reconfigured.
255 MaybeAttachFrameDecryptorToMediaChannel(
256 ssrc_, worker_thread_, frame_decryptor_, media_channel_, stopped_);
Marina Ciocea3e9af7f2020-04-01 07:46:16 +0200257
258 if (media_channel_ && ssrc_.has_value() && !stopped_) {
259 worker_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
260 RTC_DCHECK_RUN_ON(worker_thread_);
261 if (!frame_transformer_)
262 return;
263 media_channel_->SetDepacketizerToDecoderFrameTransformer(
264 *ssrc_, frame_transformer_);
265 });
266 }
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100267}
268
269void AudioRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
270 observer_ = observer;
271 // Deliver any notifications the observer may have missed by being set late.
272 if (received_first_packet_ && observer_) {
273 observer_->OnFirstPacketReceived(media_type());
274 }
275}
276
Ruslan Burakov4bac79e2019-04-03 19:55:33 +0200277void AudioRtpReceiver::SetJitterBufferMinimumDelay(
278 absl::optional<double> delay_seconds) {
Ruslan Burakov428dcb22019-04-18 17:49:49 +0200279 delay_->Set(delay_seconds);
Ruslan Burakov4bac79e2019-04-03 19:55:33 +0200280}
281
Ruslan Burakov501bfba2019-02-11 10:29:19 +0100282void AudioRtpReceiver::SetMediaChannel(cricket::MediaChannel* media_channel) {
283 RTC_DCHECK(media_channel == nullptr ||
284 media_channel->media_type() == media_type());
285 media_channel_ = static_cast<cricket::VoiceMediaChannel*>(media_channel);
286}
287
288void AudioRtpReceiver::NotifyFirstPacketReceived() {
289 if (observer_) {
290 observer_->OnFirstPacketReceived(media_type());
291 }
292 received_first_packet_ = true;
293}
294
295} // namespace webrtc