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