Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Side by Side Diff: webrtc/modules/audio_mixer/audio_mixer_impl.cc

Issue 2401603003: Reland of https://codereview.webrtc.org/2396483002/ (Closed)
Patch Set: Changed LOG macro. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" 11 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <functional> 14 #include <functional>
15 #include <utility> 15 #include <utility>
16 16
17 #include "webrtc/base/logging.h"
17 #include "webrtc/modules/audio_mixer/audio_frame_manipulator.h" 18 #include "webrtc/modules/audio_mixer/audio_frame_manipulator.h"
18 #include "webrtc/modules/utility/include/audio_frame_operations.h" 19 #include "webrtc/modules/utility/include/audio_frame_operations.h"
19 #include "webrtc/system_wrappers/include/trace.h" 20 #include "webrtc/system_wrappers/include/trace.h"
20 21
21 namespace webrtc { 22 namespace webrtc {
22 namespace { 23 namespace {
23 24
24 class SourceFrame { 25 class SourceFrame {
25 public: 26 public:
26 SourceFrame(MixerAudioSource* p, AudioFrame* a, bool m, bool was_mixed_before) 27 SourceFrame(AudioSourceWithMixStatus* audio_source,
27 : audio_source_(p), 28 AudioFrame* audio_frame,
28 audio_frame_(a), 29 bool muted)
29 muted_(m), 30 : audio_source_(audio_source), audio_frame_(audio_frame), muted_(muted) {
30 was_mixed_before_(was_mixed_before) {
31 if (!muted_) { 31 if (!muted_) {
32 energy_ = NewMixerCalculateEnergy(*a); 32 energy_ = AudioMixerCalculateEnergy(*audio_frame);
33 } 33 }
34 } 34 }
35 35
36 SourceFrame(MixerAudioSource* p, 36 SourceFrame(AudioSourceWithMixStatus* audio_source,
37 AudioFrame* a, 37 AudioFrame* audio_frame,
38 bool m, 38 bool muted,
39 bool was_mixed_before,
40 uint32_t energy) 39 uint32_t energy)
41 : audio_source_(p), 40 : audio_source_(audio_source),
42 audio_frame_(a), 41 audio_frame_(audio_frame),
43 muted_(m), 42 muted_(muted),
44 energy_(energy), 43 energy_(energy) {}
45 was_mixed_before_(was_mixed_before) {}
46 44
47 // a.shouldMixBefore(b) is used to select mixer participants. 45 // a.ShouldMixBefore(b) is used to select mixer sources.
48 bool shouldMixBefore(const SourceFrame& other) const { 46 bool ShouldMixBefore(const SourceFrame& other) const {
49 if (muted_ != other.muted_) { 47 if (muted_ != other.muted_) {
50 return other.muted_; 48 return other.muted_;
51 } 49 }
52 50
53 const auto our_activity = audio_frame_->vad_activity_; 51 const auto our_activity = audio_frame_->vad_activity_;
54 const auto other_activity = other.audio_frame_->vad_activity_; 52 const auto other_activity = other.audio_frame_->vad_activity_;
55 53
56 if (our_activity != other_activity) { 54 if (our_activity != other_activity) {
57 return our_activity == AudioFrame::kVadActive; 55 return our_activity == AudioFrame::kVadActive;
58 } 56 }
59 57
60 return energy_ > other.energy_; 58 return energy_ > other.energy_;
61 } 59 }
62 60
63 MixerAudioSource* audio_source_; 61 AudioSourceWithMixStatus* audio_source_ = nullptr;
64 AudioFrame* audio_frame_; 62 AudioFrame* audio_frame_ = nullptr;
65 bool muted_; 63 bool muted_ = true;
66 uint32_t energy_; 64 uint32_t energy_ = 0;
67 bool was_mixed_before_;
68 }; 65 };
69 66
70 // Remixes a frame between stereo and mono. 67 // Remixes a frame between stereo and mono.
71 void RemixFrame(AudioFrame* frame, size_t number_of_channels) { 68 void RemixFrame(AudioFrame* frame, size_t number_of_channels) {
72 RTC_DCHECK(number_of_channels == 1 || number_of_channels == 2); 69 RTC_DCHECK(number_of_channels == 1 || number_of_channels == 2);
73 if (frame->num_channels_ == 1 && number_of_channels == 2) { 70 if (frame->num_channels_ == 1 && number_of_channels == 2) {
74 AudioFrameOperations::MonoToStereo(frame); 71 AudioFrameOperations::MonoToStereo(frame);
75 } else if (frame->num_channels_ == 2 && number_of_channels == 1) { 72 } else if (frame->num_channels_ == 2 && number_of_channels == 1) {
76 AudioFrameOperations::StereoToMono(frame); 73 AudioFrameOperations::StereoToMono(frame);
77 } 74 }
78 } 75 }
79 76
80 void Ramp(const std::vector<SourceFrame>& mixed_sources_and_frames) { 77 void Ramp(const std::vector<SourceFrame>& mixed_sources_and_frames) {
81 for (const auto& source_frame : mixed_sources_and_frames) { 78 for (const auto& source_frame : mixed_sources_and_frames) {
82 // Ramp in previously unmixed. 79 // Ramp in previously unmixed.
83 if (!source_frame.was_mixed_before_) { 80 if (!source_frame.audio_source_->WasMixed()) {
84 NewMixerRampIn(source_frame.audio_frame_); 81 NewMixerRampIn(source_frame.audio_frame_);
85 } 82 }
86 83
87 const bool is_mixed = source_frame.audio_source_->IsMixed(); 84 const bool is_mixed = source_frame.audio_source_->IsMixed();
88 // Ramp out currently unmixed. 85 // Ramp out currently unmixed.
89 if (source_frame.was_mixed_before_ && !is_mixed) { 86 if (source_frame.audio_source_->WasMixed() && !is_mixed) {
90 NewMixerRampOut(source_frame.audio_frame_); 87 NewMixerRampOut(source_frame.audio_frame_);
91 } 88 }
92 } 89 }
93 } 90 }
94 91
95 // Mix the AudioFrames stored in audioFrameList into mixed_audio. 92 // Mix the AudioFrames stored in audioFrameList into mixed_audio.
96 int32_t MixFromList(AudioFrame* mixed_audio, 93 int32_t MixFromList(AudioFrame* mixed_audio,
97 const AudioFrameList& audio_frame_list, 94 const AudioFrameList& audio_frame_list,
98 int32_t id, 95 int32_t id,
99 bool use_limiter) { 96 bool use_limiter) {
(...skipping 26 matching lines...) Expand all
126 // Divide by two to avoid saturation in the mixing. 123 // Divide by two to avoid saturation in the mixing.
127 // This is only meaningful if the limiter will be used. 124 // This is only meaningful if the limiter will be used.
128 *frame >>= 1; 125 *frame >>= 1;
129 } 126 }
130 RTC_DCHECK_EQ(frame->num_channels_, mixed_audio->num_channels_); 127 RTC_DCHECK_EQ(frame->num_channels_, mixed_audio->num_channels_);
131 *mixed_audio += *frame; 128 *mixed_audio += *frame;
132 } 129 }
133 return 0; 130 return 0;
134 } 131 }
135 132
133 MixerAudioSourceList::const_iterator FindSourceInList(
134 MixerAudioSource const* audio_source,
135 MixerAudioSourceList const* audio_source_list) {
136 return std::find_if(audio_source_list->begin(), audio_source_list->end(),
137 [audio_source](const AudioSourceWithMixStatus& p) {
138 return p.audio_source() == audio_source;
139 });
140 }
141
142 MixerAudioSourceList::iterator FindSourceInList(
143 MixerAudioSource const* audio_source,
144 MixerAudioSourceList* audio_source_list) {
145 return std::find_if(audio_source_list->begin(), audio_source_list->end(),
146 [audio_source](const AudioSourceWithMixStatus& p) {
147 return p.audio_source() == audio_source;
148 });
149 }
150
136 } // namespace 151 } // namespace
137 152
138 std::unique_ptr<AudioMixer> AudioMixer::Create(int id) { 153 std::unique_ptr<AudioMixer> AudioMixer::Create(int id) {
139 return AudioMixerImpl::Create(id); 154 return AudioMixerImpl::Create(id);
140 } 155 }
141 156
142 AudioMixerImpl::AudioMixerImpl(int id, std::unique_ptr<AudioProcessing> limiter) 157 AudioMixerImpl::AudioMixerImpl(int id, std::unique_ptr<AudioProcessing> limiter)
143 : id_(id), 158 : id_(id),
144 audio_source_list_(), 159 audio_source_list_(),
145 additional_audio_source_list_(), 160 additional_audio_source_list_(),
146 num_mixed_audio_sources_(0), 161 num_mixed_audio_sources_(0),
147 use_limiter_(true), 162 use_limiter_(true),
148 time_stamp_(0), 163 time_stamp_(0),
149 limiter_(std::move(limiter)) { 164 limiter_(std::move(limiter)) {
150 SetOutputFrequency(kDefaultFrequency); 165 SetOutputFrequency(kDefaultFrequency);
151 thread_checker_.DetachFromThread(); 166 thread_checker_.DetachFromThread();
152 } 167 }
153 168
154 AudioMixerImpl::~AudioMixerImpl() {} 169 AudioMixerImpl::~AudioMixerImpl() {}
155 170
156 std::unique_ptr<AudioMixer> AudioMixerImpl::Create(int id) { 171 std::unique_ptr<AudioMixerImpl> AudioMixerImpl::Create(int id) {
157 Config config; 172 Config config;
158 config.Set<ExperimentalAgc>(new ExperimentalAgc(false)); 173 config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
159 std::unique_ptr<AudioProcessing> limiter(AudioProcessing::Create(config)); 174 std::unique_ptr<AudioProcessing> limiter(AudioProcessing::Create(config));
160 if (!limiter.get()) 175 if (!limiter.get())
161 return nullptr; 176 return nullptr;
162 177
163 if (limiter->gain_control()->set_mode(GainControl::kFixedDigital) != 178 if (limiter->gain_control()->set_mode(GainControl::kFixedDigital) !=
164 limiter->kNoError) 179 limiter->kNoError)
165 return nullptr; 180 return nullptr;
166 181
167 // We smoothly limit the mixed frame to -7 dbFS. -6 would correspond to the 182 // We smoothly limit the mixed frame to -7 dbFS. -6 would correspond to the
168 // divide-by-2 but -7 is used instead to give a bit of headroom since the 183 // divide-by-2 but -7 is used instead to give a bit of headroom since the
169 // AGC is not a hard limiter. 184 // AGC is not a hard limiter.
170 if (limiter->gain_control()->set_target_level_dbfs(7) != limiter->kNoError) 185 if (limiter->gain_control()->set_target_level_dbfs(7) != limiter->kNoError)
171 return nullptr; 186 return nullptr;
172 187
173 if (limiter->gain_control()->set_compression_gain_db(0) != limiter->kNoError) 188 if (limiter->gain_control()->set_compression_gain_db(0) != limiter->kNoError)
174 return nullptr; 189 return nullptr;
175 190
176 if (limiter->gain_control()->enable_limiter(true) != limiter->kNoError) 191 if (limiter->gain_control()->enable_limiter(true) != limiter->kNoError)
177 return nullptr; 192 return nullptr;
178 193
179 if (limiter->gain_control()->Enable(true) != limiter->kNoError) 194 if (limiter->gain_control()->Enable(true) != limiter->kNoError)
180 return nullptr; 195 return nullptr;
181 196
182 return std::unique_ptr<AudioMixer>( 197 return std::unique_ptr<AudioMixerImpl>(
183 new AudioMixerImpl(id, std::move(limiter))); 198 new AudioMixerImpl(id, std::move(limiter)));
184 } 199 }
185 200
186 void AudioMixerImpl::Mix(int sample_rate, 201 void AudioMixerImpl::Mix(int sample_rate,
187 size_t number_of_channels, 202 size_t number_of_channels,
188 AudioFrame* audio_frame_for_mixing) { 203 AudioFrame* audio_frame_for_mixing) {
189 RTC_DCHECK(number_of_channels == 1 || number_of_channels == 2); 204 RTC_DCHECK(number_of_channels == 1 || number_of_channels == 2);
190 RTC_DCHECK_RUN_ON(&thread_checker_); 205 RTC_DCHECK_RUN_ON(&thread_checker_);
191 206
192 if (sample_rate != kNbInHz && sample_rate != kWbInHz && 207 if (sample_rate != kNbInHz && sample_rate != kWbInHz &&
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 274
260 int32_t AudioMixerImpl::SetMixabilityStatus(MixerAudioSource* audio_source, 275 int32_t AudioMixerImpl::SetMixabilityStatus(MixerAudioSource* audio_source,
261 bool mixable) { 276 bool mixable) {
262 if (!mixable) { 277 if (!mixable) {
263 // Anonymous audio sources are in a separate list. Make sure that the 278 // Anonymous audio sources are in a separate list. Make sure that the
264 // audio source is in the _audioSourceList if it is being mixed. 279 // audio source is in the _audioSourceList if it is being mixed.
265 SetAnonymousMixabilityStatus(audio_source, false); 280 SetAnonymousMixabilityStatus(audio_source, false);
266 } 281 }
267 { 282 {
268 rtc::CritScope lock(&crit_); 283 rtc::CritScope lock(&crit_);
269 const bool is_mixed = 284 const bool is_mixed = FindSourceInList(audio_source, &audio_source_list_) !=
270 IsAudioSourceInList(*audio_source, audio_source_list_); 285 audio_source_list_.end();
271 // API must be called with a new state. 286 // API must be called with a new state.
272 if (!(mixable ^ is_mixed)) { 287 if (!(mixable ^ is_mixed)) {
273 WEBRTC_TRACE(kTraceWarning, kTraceAudioMixerServer, id_, 288 WEBRTC_TRACE(kTraceWarning, kTraceAudioMixerServer, id_,
274 "Mixable is aready %s", is_mixed ? "ON" : "off"); 289 "Mixable is aready %s", is_mixed ? "ON" : "off");
275 return -1; 290 return -1;
276 } 291 }
277 bool success = false; 292 bool success = false;
278 if (mixable) { 293 if (mixable) {
279 success = AddAudioSourceToList(audio_source, &audio_source_list_); 294 success = AddAudioSourceToList(audio_source, &audio_source_list_);
280 } else { 295 } else {
(...skipping 12 matching lines...) Expand all
293 } 308 }
294 num_mixed_audio_sources_ = 309 num_mixed_audio_sources_ =
295 num_mixed_non_anonymous + additional_audio_source_list_.size(); 310 num_mixed_non_anonymous + additional_audio_source_list_.size();
296 } 311 }
297 return 0; 312 return 0;
298 } 313 }
299 314
300 bool AudioMixerImpl::MixabilityStatus( 315 bool AudioMixerImpl::MixabilityStatus(
301 const MixerAudioSource& audio_source) const { 316 const MixerAudioSource& audio_source) const {
302 rtc::CritScope lock(&crit_); 317 rtc::CritScope lock(&crit_);
303 return IsAudioSourceInList(audio_source, audio_source_list_); 318 return FindSourceInList(&audio_source, &audio_source_list_) !=
319 audio_source_list_.end();
304 } 320 }
305 321
306 int32_t AudioMixerImpl::SetAnonymousMixabilityStatus( 322 int32_t AudioMixerImpl::SetAnonymousMixabilityStatus(
307 MixerAudioSource* audio_source, 323 MixerAudioSource* audio_source,
308 bool anonymous) { 324 bool anonymous) {
309 rtc::CritScope lock(&crit_); 325 rtc::CritScope lock(&crit_);
310 if (IsAudioSourceInList(*audio_source, additional_audio_source_list_)) { 326 if (FindSourceInList(audio_source, &additional_audio_source_list_) !=
327 additional_audio_source_list_.end()) {
311 if (anonymous) { 328 if (anonymous) {
312 return 0; 329 return 0;
313 } 330 }
314 if (!RemoveAudioSourceFromList(audio_source, 331 if (!RemoveAudioSourceFromList(audio_source,
315 &additional_audio_source_list_)) { 332 &additional_audio_source_list_)) {
316 WEBRTC_TRACE(kTraceError, kTraceAudioMixerServer, id_, 333 WEBRTC_TRACE(kTraceError, kTraceAudioMixerServer, id_,
317 "unable to remove audio_source from anonymous list"); 334 "unable to remove audio_source from anonymous list");
318 RTC_NOTREACHED(); 335 RTC_NOTREACHED();
319 return -1; 336 return -1;
320 } 337 }
(...skipping 13 matching lines...) Expand all
334 return -1; 351 return -1;
335 } 352 }
336 return AddAudioSourceToList(audio_source, &additional_audio_source_list_) 353 return AddAudioSourceToList(audio_source, &additional_audio_source_list_)
337 ? 0 354 ? 0
338 : -1; 355 : -1;
339 } 356 }
340 357
341 bool AudioMixerImpl::AnonymousMixabilityStatus( 358 bool AudioMixerImpl::AnonymousMixabilityStatus(
342 const MixerAudioSource& audio_source) const { 359 const MixerAudioSource& audio_source) const {
343 rtc::CritScope lock(&crit_); 360 rtc::CritScope lock(&crit_);
344 return IsAudioSourceInList(audio_source, additional_audio_source_list_); 361 return FindSourceInList(&audio_source, &additional_audio_source_list_) !=
362 additional_audio_source_list_.end();
345 } 363 }
346 364
347 AudioFrameList AudioMixerImpl::GetNonAnonymousAudio() const { 365 AudioFrameList AudioMixerImpl::GetNonAnonymousAudio() {
348 RTC_DCHECK_RUN_ON(&thread_checker_); 366 RTC_DCHECK_RUN_ON(&thread_checker_);
349 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_, 367 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_,
350 "GetNonAnonymousAudio()"); 368 "GetNonAnonymousAudio()");
351 AudioFrameList result; 369 AudioFrameList result;
352 std::vector<SourceFrame> audio_source_mixing_data_list; 370 std::vector<SourceFrame> audio_source_mixing_data_list;
353 std::vector<SourceFrame> ramp_list; 371 std::vector<SourceFrame> ramp_list;
354 372
355 // Get audio source audio and put it in the struct vector. 373 // Get audio source audio and put it in the struct vector.
356 for (auto* const audio_source : audio_source_list_) { 374 for (auto& source_and_status : audio_source_list_) {
357 auto audio_frame_with_info = audio_source->GetAudioFrameWithMuted( 375 auto audio_frame_with_info =
358 id_, static_cast<int>(OutputFrequency())); 376 source_and_status.audio_source()->GetAudioFrameWithMuted(
377 id_, static_cast<int>(OutputFrequency()));
359 378
360 const auto audio_frame_info = audio_frame_with_info.audio_frame_info; 379 const auto audio_frame_info = audio_frame_with_info.audio_frame_info;
361 AudioFrame* audio_source_audio_frame = audio_frame_with_info.audio_frame; 380 AudioFrame* audio_source_audio_frame = audio_frame_with_info.audio_frame;
362 381
363 if (audio_frame_info == MixerAudioSource::AudioFrameInfo::kError) { 382 if (audio_frame_info == MixerAudioSource::AudioFrameInfo::kError) {
364 WEBRTC_TRACE(kTraceWarning, kTraceAudioMixerServer, id_, 383 WEBRTC_TRACE(kTraceWarning, kTraceAudioMixerServer, id_,
365 "failed to GetAudioFrameWithMuted() from participant"); 384 "failed to GetAudioFrameWithMuted() from source");
366 continue; 385 continue;
367 } 386 }
368 audio_source_mixing_data_list.emplace_back( 387 audio_source_mixing_data_list.emplace_back(
369 audio_source, audio_source_audio_frame, 388 &source_and_status, audio_source_audio_frame,
370 audio_frame_info == MixerAudioSource::AudioFrameInfo::kMuted, 389 audio_frame_info == MixerAudioSource::AudioFrameInfo::kMuted);
371 audio_source->WasMixed());
372 } 390 }
373 391
374 // Sort frames by sorting function. 392 // Sort frames by sorting function.
375 std::sort(audio_source_mixing_data_list.begin(), 393 std::sort(audio_source_mixing_data_list.begin(),
376 audio_source_mixing_data_list.end(), 394 audio_source_mixing_data_list.end(),
377 std::mem_fn(&SourceFrame::shouldMixBefore)); 395 std::mem_fn(&SourceFrame::ShouldMixBefore));
378 396
379 int max_audio_frame_counter = kMaximumAmountOfMixedAudioSources; 397 int max_audio_frame_counter = kMaximumAmountOfMixedAudioSources;
380 398
381 // Go through list in order and put unmuted frames in result list. 399 // Go through list in order and put unmuted frames in result list.
382 for (const SourceFrame& p : audio_source_mixing_data_list) { 400 for (const auto& p : audio_source_mixing_data_list) {
383 // Filter muted. 401 // Filter muted.
384 if (p.muted_) { 402 if (p.muted_) {
385 p.audio_source_->SetIsMixed(false); 403 p.audio_source_->SetIsMixed(false);
386 continue; 404 continue;
387 } 405 }
388 406
389 // Add frame to result vector for mixing. 407 // Add frame to result vector for mixing.
390 bool is_mixed = false; 408 bool is_mixed = false;
391 if (max_audio_frame_counter > 0) { 409 if (max_audio_frame_counter > 0) {
392 --max_audio_frame_counter; 410 --max_audio_frame_counter;
393 result.push_back(p.audio_frame_); 411 result.push_back(p.audio_frame_);
394 ramp_list.emplace_back(p.audio_source_, p.audio_frame_, false, 412 ramp_list.emplace_back(p.audio_source_, p.audio_frame_, false, -1);
395 p.was_mixed_before_, -1);
396 is_mixed = true; 413 is_mixed = true;
397 } 414 }
398 p.audio_source_->SetIsMixed(is_mixed); 415 p.audio_source_->SetIsMixed(is_mixed);
399 } 416 }
400 Ramp(ramp_list); 417 Ramp(ramp_list);
401 return result; 418 return result;
402 } 419 }
403 420
404 AudioFrameList AudioMixerImpl::GetAnonymousAudio() const { 421 AudioFrameList AudioMixerImpl::GetAnonymousAudio() {
405 RTC_DCHECK_RUN_ON(&thread_checker_); 422 RTC_DCHECK_RUN_ON(&thread_checker_);
406 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_, 423 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_,
407 "GetAnonymousAudio()"); 424 "GetAnonymousAudio()");
408 // The GetAudioFrameWithMuted() callback may result in the audio source being
409 // removed from additionalAudioFramesList_. If that happens it will
410 // invalidate any iterators. Create a copy of the audio sources list such
411 // that the list of participants can be traversed safely.
412 std::vector<SourceFrame> ramp_list; 425 std::vector<SourceFrame> ramp_list;
413 MixerAudioSourceList additional_audio_sources_list;
414 AudioFrameList result; 426 AudioFrameList result;
415 additional_audio_sources_list.insert(additional_audio_sources_list.begin(), 427 for (auto& source_and_status : additional_audio_source_list_) {
416 additional_audio_source_list_.begin(),
417 additional_audio_source_list_.end());
418
419 for (const auto& audio_source : additional_audio_sources_list) {
420 const auto audio_frame_with_info = 428 const auto audio_frame_with_info =
421 audio_source->GetAudioFrameWithMuted(id_, OutputFrequency()); 429 source_and_status.audio_source()->GetAudioFrameWithMuted(
430 id_, OutputFrequency());
422 const auto ret = audio_frame_with_info.audio_frame_info; 431 const auto ret = audio_frame_with_info.audio_frame_info;
423 AudioFrame* audio_frame = audio_frame_with_info.audio_frame; 432 AudioFrame* audio_frame = audio_frame_with_info.audio_frame;
424 if (ret == MixerAudioSource::AudioFrameInfo::kError) { 433 if (ret == MixerAudioSource::AudioFrameInfo::kError) {
425 WEBRTC_TRACE(kTraceWarning, kTraceAudioMixerServer, id_, 434 WEBRTC_TRACE(kTraceWarning, kTraceAudioMixerServer, id_,
426 "failed to GetAudioFrameWithMuted() from audio_source"); 435 "failed to GetAudioFrameWithMuted() from audio_source");
427 continue; 436 continue;
428 } 437 }
429 if (ret != MixerAudioSource::AudioFrameInfo::kMuted) { 438 if (ret != MixerAudioSource::AudioFrameInfo::kMuted) {
430 result.push_back(audio_frame); 439 result.push_back(audio_frame);
431 ramp_list.emplace_back(audio_source, audio_frame, false, 440 ramp_list.emplace_back(&source_and_status, audio_frame, false, 0);
432 audio_source->IsMixed(), 0); 441 source_and_status.SetIsMixed(true);
433 audio_source->SetIsMixed(true);
434 } 442 }
435 } 443 }
436 Ramp(ramp_list); 444 Ramp(ramp_list);
437 return result; 445 return result;
438 } 446 }
439 447
440 bool AudioMixerImpl::IsAudioSourceInList(
441 const MixerAudioSource& audio_source,
442 const MixerAudioSourceList& audio_source_list) const {
443 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_,
444 "IsAudioSourceInList(audio_source,audio_source_list)");
445 return std::find(audio_source_list.begin(), audio_source_list.end(),
446 &audio_source) != audio_source_list.end();
447 }
448
449 bool AudioMixerImpl::AddAudioSourceToList( 448 bool AudioMixerImpl::AddAudioSourceToList(
450 MixerAudioSource* audio_source, 449 MixerAudioSource* audio_source,
451 MixerAudioSourceList* audio_source_list) const { 450 MixerAudioSourceList* audio_source_list) const {
452 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_, 451 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_,
453 "AddAudioSourceToList(audio_source, audio_source_list)"); 452 "AddAudioSourceToList(audio_source, audio_source_list)");
454 audio_source_list->push_back(audio_source); 453 audio_source_list->emplace_back(audio_source);
455 // Make sure that the mixed status is correct for new MixerAudioSource.
456 audio_source->ResetMixedStatus();
457 return true; 454 return true;
458 } 455 }
459 456
460 bool AudioMixerImpl::RemoveAudioSourceFromList( 457 bool AudioMixerImpl::RemoveAudioSourceFromList(
461 MixerAudioSource* audio_source, 458 MixerAudioSource* audio_source,
462 MixerAudioSourceList* audio_source_list) const { 459 MixerAudioSourceList* audio_source_list) const {
463 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_, 460 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_,
464 "RemoveAudioSourceFromList(audio_source, audio_source_list)"); 461 "RemoveAudioSourceFromList(audio_source, audio_source_list)");
465 const auto iter = std::find(audio_source_list->begin(), 462 const auto iter = FindSourceInList(audio_source, audio_source_list);
466 audio_source_list->end(), audio_source);
467 if (iter != audio_source_list->end()) { 463 if (iter != audio_source_list->end()) {
468 audio_source_list->erase(iter); 464 audio_source_list->erase(iter);
469 // AudioSource is no longer mixed, reset to default.
470 audio_source->ResetMixedStatus();
471 return true; 465 return true;
472 } else { 466 } else {
473 return false; 467 return false;
474 } 468 }
475 } 469 }
476 470
477 bool AudioMixerImpl::LimitMixedAudio(AudioFrame* mixed_audio) const { 471 bool AudioMixerImpl::LimitMixedAudio(AudioFrame* mixed_audio) const {
478 RTC_DCHECK_RUN_ON(&thread_checker_); 472 RTC_DCHECK_RUN_ON(&thread_checker_);
479 if (!use_limiter_) { 473 if (!use_limiter_) {
480 return true; 474 return true;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 return level; 506 return level;
513 } 507 }
514 508
515 int AudioMixerImpl::GetOutputAudioLevelFullRange() { 509 int AudioMixerImpl::GetOutputAudioLevelFullRange() {
516 RTC_DCHECK_RUN_ON(&thread_checker_); 510 RTC_DCHECK_RUN_ON(&thread_checker_);
517 const int level = audio_level_.LevelFullRange(); 511 const int level = audio_level_.LevelFullRange();
518 WEBRTC_TRACE(kTraceStateInfo, kTraceAudioMixerServer, id_, 512 WEBRTC_TRACE(kTraceStateInfo, kTraceAudioMixerServer, id_,
519 "GetAudioOutputLevelFullRange() => level=%d", level); 513 "GetAudioOutputLevelFullRange() => level=%d", level);
520 return level; 514 return level;
521 } 515 }
516
517 bool AudioMixerImpl::GetAudioSourceMixabilityStatusForTest(
518 MixerAudioSource* audio_source) {
519 RTC_DCHECK_RUN_ON(&thread_checker_);
520 rtc::CritScope lock(&crit_);
521
522 const auto non_anonymous_iter =
523 FindSourceInList(audio_source, &audio_source_list_);
524 if (non_anonymous_iter != audio_source_list_.end()) {
525 return non_anonymous_iter->IsMixed();
526 }
527
528 const auto anonymous_iter =
529 FindSourceInList(audio_source, &additional_audio_source_list_);
530 if (anonymous_iter != audio_source_list_.end()) {
531 return anonymous_iter->IsMixed();
532 }
533
534 LOG(LS_ERROR) << "Audio source unknown";
535 return false;
536 }
522 } // namespace webrtc 537 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_mixer/audio_mixer_impl.h ('k') | webrtc/modules/audio_mixer/audio_source_with_mix_status.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698