blob: 705ec1bc40ac811cc83da0c8a12fa03633070585 [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/audio_rtp_receiver.h"
12
13#include <stddef.h>
Jonas Olssona4d87372019-07-05 17:08:3314
Harald Alvestrandc24a2182022-02-23 13:44:5915#include <string>
Ruslan Burakov501bfba2019-02-11 09:29:1916#include <utility>
17#include <vector>
18
Artem Titovd15a5752021-02-10 13:31:2419#include "api/sequence_checker.h"
Ruslan Burakov501bfba2019-02-11 09:29:1920#include "pc/audio_track.h"
Markus Handella1b82012021-05-26 16:56:3021#include "pc/media_stream_track_proxy.h"
Ruslan Burakov501bfba2019-02-11 09:29:1922#include "rtc_base/checks.h"
Ruslan Burakov501bfba2019-02-11 09:29:1923
24namespace webrtc {
25
Tommi6589def2022-02-17 22:36:4726AudioRtpReceiver::AudioRtpReceiver(
27 rtc::Thread* worker_thread,
28 std::string receiver_id,
29 std::vector<std::string> stream_ids,
30 bool is_unified_plan,
Harald Alvestrandc0d44d92022-12-13 12:57:2431 cricket::VoiceMediaReceiveChannelInterface* voice_channel /*= nullptr*/)
Ruslan Burakov501bfba2019-02-11 09:29:1932 : AudioRtpReceiver(worker_thread,
33 receiver_id,
Henrik Boströmc335b0e2021-04-08 05:25:3834 CreateStreamsFromIds(std::move(stream_ids)),
Tommi6589def2022-02-17 22:36:4735 is_unified_plan,
36 voice_channel) {}
Ruslan Burakov501bfba2019-02-11 09:29:1937
38AudioRtpReceiver::AudioRtpReceiver(
39 rtc::Thread* worker_thread,
40 const std::string& receiver_id,
Henrik Boströmc335b0e2021-04-08 05:25:3841 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams,
Tommi6589def2022-02-17 22:36:4742 bool is_unified_plan,
Harald Alvestrandc0d44d92022-12-13 12:57:2443 cricket::VoiceMediaReceiveChannelInterface* voice_channel /*= nullptr*/)
Ruslan Burakov501bfba2019-02-11 09:29:1944 : worker_thread_(worker_thread),
45 id_(receiver_id),
Tommi87f70902021-04-27 12:43:0846 source_(rtc::make_ref_counted<RemoteAudioSource>(
Henrik Boströmc335b0e2021-04-08 05:25:3847 worker_thread,
48 is_unified_plan
49 ? RemoteAudioSource::OnAudioChannelGoneAction::kSurvive
50 : RemoteAudioSource::OnAudioChannelGoneAction::kEnd)),
Harald Alvestrand1ee33252020-09-24 13:31:1551 track_(AudioTrackProxyWithInternal<AudioTrack>::Create(
52 rtc::Thread::Current(),
53 AudioTrack::Create(receiver_id, source_))),
Tommi6589def2022-02-17 22:36:4754 media_channel_(voice_channel),
55 cached_track_enabled_(track_->internal()->enabled()),
Ruslan Burakov428dcb22019-04-18 15:49:4956 attachment_id_(GenerateUniqueId()),
Tommi4ccdf9322021-05-17 12:50:1057 worker_thread_safety_(PendingTaskSafetyFlag::CreateDetachedInactive()) {
Ruslan Burakov501bfba2019-02-11 09:29:1958 RTC_DCHECK(worker_thread_);
59 RTC_DCHECK(track_->GetSource()->remote());
60 track_->RegisterObserver(this);
61 track_->GetSource()->RegisterAudioObserver(this);
62 SetStreams(streams);
63}
64
65AudioRtpReceiver::~AudioRtpReceiver() {
Tommi4ccdf9322021-05-17 12:50:1066 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
Tommi4ccdf9322021-05-17 12:50:1067 RTC_DCHECK(!media_channel_);
68
Ruslan Burakov501bfba2019-02-11 09:29:1969 track_->GetSource()->UnregisterAudioObserver(this);
70 track_->UnregisterObserver(this);
Ruslan Burakov501bfba2019-02-11 09:29:1971}
72
73void AudioRtpReceiver::OnChanged() {
Tommi4ccdf9322021-05-17 12:50:1074 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
Tommi6589def2022-02-17 22:36:4775 const bool enabled = track_->internal()->enabled();
76 if (cached_track_enabled_ == enabled)
77 return;
78 cached_track_enabled_ = enabled;
Danil Chapovalova30439b2022-07-07 08:08:4979 worker_thread_->PostTask(SafeTask(worker_thread_safety_, [this, enabled]() {
80 RTC_DCHECK_RUN_ON(worker_thread_);
81 Reconfigure(enabled);
82 }));
Ruslan Burakov501bfba2019-02-11 09:29:1983}
84
Tommi4ccdf9322021-05-17 12:50:1085void AudioRtpReceiver::SetOutputVolume_w(double volume) {
Danil Chapovalov6e7c2682022-07-25 13:58:2886 RTC_DCHECK_RUN_ON(worker_thread_);
Ruslan Burakov501bfba2019-02-11 09:29:1987 RTC_DCHECK_GE(volume, 0.0);
88 RTC_DCHECK_LE(volume, 10.0);
Tommi20d8d912022-02-08 20:12:1589
90 if (!media_channel_)
91 return;
92
Henrik Boström4df20ba2023-01-09 12:57:1593 signaled_ssrc_ ? media_channel_->SetOutputVolume(*signaled_ssrc_, volume)
94 : media_channel_->SetDefaultOutputVolume(volume);
Ruslan Burakov501bfba2019-02-11 09:29:1995}
96
97void AudioRtpReceiver::OnSetVolume(double volume) {
Tommi4ccdf9322021-05-17 12:50:1098 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
Ruslan Burakov501bfba2019-02-11 09:29:1999 RTC_DCHECK_GE(volume, 0);
100 RTC_DCHECK_LE(volume, 10);
Tony Herref05f2822021-11-22 18:10:19101
Tommi6589def2022-02-17 22:36:47102 bool track_enabled = track_->internal()->enabled();
Danil Chapovalov9e09a1f2022-09-08 16:38:10103 worker_thread_->BlockingCall([&]() {
Tommi6589def2022-02-17 22:36:47104 RTC_DCHECK_RUN_ON(worker_thread_);
105 // Update the cached_volume_ even when stopped, to allow clients to set
106 // the volume before starting/restarting, eg see crbug.com/1272566.
107 cached_volume_ = volume;
108 // When the track is disabled, the volume of the source, which is the
109 // corresponding WebRtc Voice Engine channel will be 0. So we do not
110 // allow setting the volume to the source when the track is disabled.
111 if (track_enabled)
112 SetOutputVolume_w(volume);
113 });
Ruslan Burakov501bfba2019-02-11 09:29:19114}
115
Tommi4ccdf9322021-05-17 12:50:10116rtc::scoped_refptr<DtlsTransportInterface> AudioRtpReceiver::dtls_transport()
117 const {
118 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
119 return dtls_transport_;
120}
121
Ruslan Burakov501bfba2019-02-11 09:29:19122std::vector<std::string> AudioRtpReceiver::stream_ids() const {
Tommi4ccdf9322021-05-17 12:50:10123 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
Ruslan Burakov501bfba2019-02-11 09:29:19124 std::vector<std::string> stream_ids(streams_.size());
125 for (size_t i = 0; i < streams_.size(); ++i)
126 stream_ids[i] = streams_[i]->id();
127 return stream_ids;
128}
129
Tommi4ccdf9322021-05-17 12:50:10130std::vector<rtc::scoped_refptr<MediaStreamInterface>>
131AudioRtpReceiver::streams() const {
132 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
133 return streams_;
134}
135
Ruslan Burakov501bfba2019-02-11 09:29:19136RtpParameters AudioRtpReceiver::GetParameters() const {
Tommi4ccdf9322021-05-17 12:50:10137 RTC_DCHECK_RUN_ON(worker_thread_);
138 if (!media_channel_)
Ruslan Burakov501bfba2019-02-11 09:29:19139 return RtpParameters();
Henrik Boström4df20ba2023-01-09 12:57:15140 auto current_ssrc = ssrc();
141 return current_ssrc.has_value()
Philipp Hancke5866e1a2023-08-25 13:28:47142 ? media_channel_->GetRtpReceiverParameters(current_ssrc.value())
Henrik Boström4df20ba2023-01-09 12:57:15143 : media_channel_->GetDefaultRtpReceiveParameters();
Ruslan Burakov501bfba2019-02-11 09:29:19144}
145
Ruslan Burakov501bfba2019-02-11 09:29:19146void AudioRtpReceiver::SetFrameDecryptor(
147 rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
Tommi4ccdf9322021-05-17 12:50:10148 RTC_DCHECK_RUN_ON(worker_thread_);
Ruslan Burakov501bfba2019-02-11 09:29:19149 frame_decryptor_ = std::move(frame_decryptor);
150 // Special Case: Set the frame decryptor to any value on any existing channel.
Henrik Boström4df20ba2023-01-09 12:57:15151 if (media_channel_ && signaled_ssrc_) {
152 media_channel_->SetFrameDecryptor(*signaled_ssrc_, frame_decryptor_);
Ruslan Burakov501bfba2019-02-11 09:29:19153 }
154}
155
156rtc::scoped_refptr<FrameDecryptorInterface>
157AudioRtpReceiver::GetFrameDecryptor() const {
Tommi4ccdf9322021-05-17 12:50:10158 RTC_DCHECK_RUN_ON(worker_thread_);
Ruslan Burakov501bfba2019-02-11 09:29:19159 return frame_decryptor_;
160}
161
162void AudioRtpReceiver::Stop() {
Tommi4ccdf9322021-05-17 12:50:10163 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
Tommi20d8d912022-02-08 20:12:15164 source_->SetState(MediaSourceInterface::kEnded);
Harald Alvestrand1ee33252020-09-24 13:31:15165 track_->internal()->set_ended();
166}
167
Florent Castelli8037fc62024-08-29 13:00:40168void AudioRtpReceiver::RestartMediaChannel(std::optional<uint32_t> ssrc) {
Danil Chapovalov6e7c2682022-07-25 13:58:28169 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
Tommi6589def2022-02-17 22:36:47170 bool enabled = track_->internal()->enabled();
Tommi20d8d912022-02-08 20:12:15171 MediaSourceInterface::SourceState state = source_->state();
Danil Chapovalov9e09a1f2022-09-08 16:38:10172 worker_thread_->BlockingCall([&]() {
Tommi6589def2022-02-17 22:36:47173 RTC_DCHECK_RUN_ON(worker_thread_);
174 RestartMediaChannel_w(std::move(ssrc), enabled, state);
175 });
Tommi20d8d912022-02-08 20:12:15176 source_->SetState(MediaSourceInterface::kLive);
Saurav Das7262fc22019-09-11 23:23:05177}
178
Tommi6589def2022-02-17 22:36:47179void AudioRtpReceiver::RestartMediaChannel_w(
Florent Castelli8037fc62024-08-29 13:00:40180 std::optional<uint32_t> ssrc,
Tommi6589def2022-02-17 22:36:47181 bool track_enabled,
182 MediaSourceInterface::SourceState state) {
Danil Chapovalov6e7c2682022-07-25 13:58:28183 RTC_DCHECK_RUN_ON(worker_thread_);
Tommi6589def2022-02-17 22:36:47184 if (!media_channel_)
185 return; // Can't restart.
186
Tommied3832b2022-03-22 10:54:09187 // Make sure the safety flag is marked as `alive` for cases where the media
188 // channel was provided via the ctor and not an explicit call to
189 // SetMediaChannel.
190 worker_thread_safety_->SetAlive();
191
Tommi6589def2022-02-17 22:36:47192 if (state != MediaSourceInterface::kInitializing) {
Henrik Boström4df20ba2023-01-09 12:57:15193 if (signaled_ssrc_ == ssrc)
Tommi6589def2022-02-17 22:36:47194 return;
Henrik Boström4df20ba2023-01-09 12:57:15195 source_->Stop(media_channel_, signaled_ssrc_);
Tommi6589def2022-02-17 22:36:47196 }
197
Henrik Boström4df20ba2023-01-09 12:57:15198 signaled_ssrc_ = std::move(ssrc);
199 source_->Start(media_channel_, signaled_ssrc_);
200 if (signaled_ssrc_) {
201 media_channel_->SetBaseMinimumPlayoutDelayMs(*signaled_ssrc_,
202 delay_.GetMs());
Tommi6589def2022-02-17 22:36:47203 }
204
205 Reconfigure(track_enabled);
206}
207
Ruslan Burakov501bfba2019-02-11 09:29:19208void AudioRtpReceiver::SetupMediaChannel(uint32_t ssrc) {
Tommi4ccdf9322021-05-17 12:50:10209 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
Saurav Das7262fc22019-09-11 23:23:05210 RestartMediaChannel(ssrc);
211}
212
213void AudioRtpReceiver::SetupUnsignaledMediaChannel() {
Tommi4ccdf9322021-05-17 12:50:10214 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
Florent Castelli8037fc62024-08-29 13:00:40215 RestartMediaChannel(std::nullopt);
Ruslan Burakov501bfba2019-02-11 09:29:19216}
217
Florent Castelli8037fc62024-08-29 13:00:40218std::optional<uint32_t> AudioRtpReceiver::ssrc() const {
Tommi4ccdf9322021-05-17 12:50:10219 RTC_DCHECK_RUN_ON(worker_thread_);
Henrik Boström4df20ba2023-01-09 12:57:15220 if (!signaled_ssrc_.has_value() && media_channel_) {
Henrik Boström175f06f2023-01-05 07:53:16221 return media_channel_->GetUnsignaledSsrc();
222 }
Henrik Boström4df20ba2023-01-09 12:57:15223 return signaled_ssrc_;
Tommi4ccdf9322021-05-17 12:50:10224}
225
Ruslan Burakov501bfba2019-02-11 09:29:19226void AudioRtpReceiver::set_stream_ids(std::vector<std::string> stream_ids) {
Tommi4ccdf9322021-05-17 12:50:10227 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
Ruslan Burakov501bfba2019-02-11 09:29:19228 SetStreams(CreateStreamsFromIds(std::move(stream_ids)));
229}
230
Tommi4ccdf9322021-05-17 12:50:10231void AudioRtpReceiver::set_transport(
232 rtc::scoped_refptr<DtlsTransportInterface> dtls_transport) {
233 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
234 dtls_transport_ = std::move(dtls_transport);
235}
236
Ruslan Burakov501bfba2019-02-11 09:29:19237void AudioRtpReceiver::SetStreams(
238 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
Tommi4ccdf9322021-05-17 12:50:10239 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
Ruslan Burakov501bfba2019-02-11 09:29:19240 // Remove remote track from any streams that are going away.
241 for (const auto& existing_stream : streams_) {
242 bool removed = true;
243 for (const auto& stream : streams) {
244 if (existing_stream->id() == stream->id()) {
245 RTC_DCHECK_EQ(existing_stream.get(), stream.get());
246 removed = false;
247 break;
248 }
249 }
250 if (removed) {
Harald Alvestrand2f7ad282022-04-21 11:35:43251 existing_stream->RemoveTrack(audio_track());
Ruslan Burakov501bfba2019-02-11 09:29:19252 }
253 }
254 // Add remote track to any streams that are new.
255 for (const auto& stream : streams) {
256 bool added = true;
257 for (const auto& existing_stream : streams_) {
258 if (stream->id() == existing_stream->id()) {
259 RTC_DCHECK_EQ(stream.get(), existing_stream.get());
260 added = false;
261 break;
262 }
263 }
264 if (added) {
Harald Alvestrand2f7ad282022-04-21 11:35:43265 stream->AddTrack(audio_track());
Ruslan Burakov501bfba2019-02-11 09:29:19266 }
267 }
268 streams_ = streams;
269}
270
271std::vector<RtpSource> AudioRtpReceiver::GetSources() const {
Tommi4ccdf9322021-05-17 12:50:10272 RTC_DCHECK_RUN_ON(worker_thread_);
Henrik Boström4df20ba2023-01-09 12:57:15273 auto current_ssrc = ssrc();
274 if (!media_channel_ || !current_ssrc.has_value()) {
Ruslan Burakov501bfba2019-02-11 09:29:19275 return {};
276 }
Henrik Boström4df20ba2023-01-09 12:57:15277 return media_channel_->GetSources(current_ssrc.value());
Ruslan Burakov501bfba2019-02-11 09:29:19278}
279
Harald Alvestrandb0e70572024-04-23 14:04:18280void AudioRtpReceiver::SetFrameTransformer(
Harald Alvestranda6544372023-11-13 09:33:56281 rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) {
Tommi4ccdf9322021-05-17 12:50:10282 RTC_DCHECK_RUN_ON(worker_thread_);
283 if (media_channel_) {
Henrik Boström4df20ba2023-01-09 12:57:15284 media_channel_->SetDepacketizerToDecoderFrameTransformer(
285 signaled_ssrc_.value_or(0), frame_transformer);
Tommi4ccdf9322021-05-17 12:50:10286 }
287 frame_transformer_ = std::move(frame_transformer);
Marina Ciocea3e9af7f2020-04-01 05:46:16288}
289
Tommi6589def2022-02-17 22:36:47290void AudioRtpReceiver::Reconfigure(bool track_enabled) {
Danil Chapovalov6e7c2682022-07-25 13:58:28291 RTC_DCHECK_RUN_ON(worker_thread_);
Tommi4ccdf9322021-05-17 12:50:10292 RTC_DCHECK(media_channel_);
Marina Ciocea3e9af7f2020-04-01 05:46:16293
Tommi6589def2022-02-17 22:36:47294 SetOutputVolume_w(track_enabled ? cached_volume_ : 0);
Tommi4ccdf9322021-05-17 12:50:10295
Henrik Boström4df20ba2023-01-09 12:57:15296 if (signaled_ssrc_ && frame_decryptor_) {
Tommi4ccdf9322021-05-17 12:50:10297 // Reattach the frame decryptor if we were reconfigured.
Henrik Boström4df20ba2023-01-09 12:57:15298 media_channel_->SetFrameDecryptor(*signaled_ssrc_, frame_decryptor_);
Tommi4ccdf9322021-05-17 12:50:10299 }
300
301 if (frame_transformer_) {
302 media_channel_->SetDepacketizerToDecoderFrameTransformer(
Henrik Boström4df20ba2023-01-09 12:57:15303 signaled_ssrc_.value_or(0), frame_transformer_);
Marina Ciocea3e9af7f2020-04-01 05:46:16304 }
Ruslan Burakov501bfba2019-02-11 09:29:19305}
306
307void AudioRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
Tommi4ccdf9322021-05-17 12:50:10308 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
Ruslan Burakov501bfba2019-02-11 09:29:19309 observer_ = observer;
310 // Deliver any notifications the observer may have missed by being set late.
311 if (received_first_packet_ && observer_) {
312 observer_->OnFirstPacketReceived(media_type());
313 }
314}
315
Ruslan Burakov4bac79e2019-04-03 17:55:33316void AudioRtpReceiver::SetJitterBufferMinimumDelay(
Florent Castelli8037fc62024-08-29 13:00:40317 std::optional<double> delay_seconds) {
Tommi4ccdf9322021-05-17 12:50:10318 RTC_DCHECK_RUN_ON(worker_thread_);
319 delay_.Set(delay_seconds);
Henrik Boström4df20ba2023-01-09 12:57:15320 if (media_channel_ && signaled_ssrc_)
321 media_channel_->SetBaseMinimumPlayoutDelayMs(*signaled_ssrc_,
322 delay_.GetMs());
Ruslan Burakov4bac79e2019-04-03 17:55:33323}
324
Harald Alvestrand36fafc82022-12-08 08:47:42325void AudioRtpReceiver::SetMediaChannel(
326 cricket::MediaReceiveChannelInterface* media_channel) {
Tommi6589def2022-02-17 22:36:47327 RTC_DCHECK_RUN_ON(worker_thread_);
Ruslan Burakov501bfba2019-02-11 09:29:19328 RTC_DCHECK(media_channel == nullptr ||
329 media_channel->media_type() == media_type());
Tommi6589def2022-02-17 22:36:47330 if (!media_channel && media_channel_)
331 SetOutputVolume_w(0.0);
Tommi4ccdf9322021-05-17 12:50:10332
Tommi4ccdf9322021-05-17 12:50:10333 media_channel ? worker_thread_safety_->SetAlive()
334 : worker_thread_safety_->SetNotAlive();
Harald Alvestrandc0d44d92022-12-13 12:57:24335 media_channel_ =
336 static_cast<cricket::VoiceMediaReceiveChannelInterface*>(media_channel);
Ruslan Burakov501bfba2019-02-11 09:29:19337}
338
339void AudioRtpReceiver::NotifyFirstPacketReceived() {
Tommi4ccdf9322021-05-17 12:50:10340 RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
Ruslan Burakov501bfba2019-02-11 09:29:19341 if (observer_) {
342 observer_->OnFirstPacketReceived(media_type());
343 }
344 received_first_packet_ = true;
345}
346
347} // namespace webrtc