OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <string> | 5 #include <string> |
6 | 6 |
7 #include "services/media/audio/audio_output.h" | 7 #include "services/media/audio/audio_output.h" |
8 #include "services/media/audio/audio_output_manager.h" | 8 #include "services/media/audio/audio_output_manager.h" |
9 #include "services/media/audio/audio_server_impl.h" | 9 #include "services/media/audio/audio_server_impl.h" |
10 #include "services/media/audio/audio_track_to_output_link.h" | 10 #include "services/media/audio/audio_track_to_output_link.h" |
11 #include "services/media/audio/platform/generic/throttle_output.h" | 11 #include "services/media/audio/platform/generic/throttle_output.h" |
12 #if defined(OS_LINUX) | |
13 #include "services/media/audio/platform/linux/alsa_output.h" | |
14 #endif | |
12 | 15 |
13 namespace mojo { | 16 namespace mojo { |
14 namespace media { | 17 namespace media { |
15 namespace audio { | 18 namespace audio { |
16 | 19 |
17 static constexpr size_t THREAD_POOL_SZ = 2; | 20 static constexpr size_t THREAD_POOL_SZ = 2; |
18 static const std::string THREAD_PREFIX("AudioMixer"); | 21 static const std::string THREAD_PREFIX("AudioMixer"); |
19 | 22 |
20 AudioOutputManager::AudioOutputManager(AudioServerImpl* server) | 23 AudioOutputManager::AudioOutputManager(AudioServerImpl* server) |
21 : server_(server) { | 24 : server_(server) { |
22 } | 25 } |
23 | 26 |
24 AudioOutputManager::~AudioOutputManager() { | 27 AudioOutputManager::~AudioOutputManager() { |
25 Shutdown(); | 28 Shutdown(); |
26 DCHECK_EQ(outputs_.size(), 0u); | 29 DCHECK_EQ(outputs_.size(), 0u); |
27 DCHECK(!thread_pool_); | 30 DCHECK(!thread_pool_); |
28 } | 31 } |
29 | 32 |
33 void AudioOutputManager::CreateAlsaOutputs() { | |
34 #if defined(OS_LINUX) | |
jeffbrown
2015/11/04 20:33:42
This to me looks like an opportunity to define a n
johngro
2015/11/06 20:22:06
Acknowledged.
We should talk sometime. I'd like
| |
35 // TODO(johngro): Do better than this. If we really want to support | |
36 // Linux/ALSA as a platform, we should be creating one output for each | |
37 // physical output in the system, matching our configuration to the physical | |
38 // output's configuration, and disabling resampling at the ALSA level. | |
39 // | |
40 // If we could own the output entirely and bypass the mixer to achieve lower | |
41 // latency, that would be even better. | |
42 AudioOutputPtr audio_out(audio::AlsaOutput::New(this)); | |
43 if (!audio_out) { return; } | |
44 | |
45 audio::AlsaOutput* alsa_out = | |
46 static_cast<audio::AlsaOutput*>(audio_out.get()); | |
jeffbrown
2015/11/04 20:33:42
Did you "git cl format"? I think this is supposed
johngro
2015/11/06 20:22:06
Done.
Solved this a different way. A long time a
| |
47 DCHECK(alsa_out); | |
48 | |
49 LpcmMediaTypeDetailsPtr config(LpcmMediaTypeDetails::New()); | |
50 DCHECK(config); | |
jeffbrown
2015/11/04 20:33:42
Might be able to omit this DCHECK. Seems like the
johngro
2015/11/06 20:22:06
The problem here is that this is not a call to ope
| |
51 config->frames_per_second = 48000; | |
52 config->samples_per_frame = 2; | |
53 config->sample_format = LpcmSampleFormat::SIGNED_16; | |
54 | |
55 if (alsa_out->Configure(config.Pass()) != MediaResult::OK) { | |
56 return; | |
57 } | |
58 | |
59 outputs_.emplace(audio_out); | |
60 #endif | |
61 } | |
62 | |
30 MediaResult AudioOutputManager::Init() { | 63 MediaResult AudioOutputManager::Init() { |
31 // Step #1: Initialize the mixing thread pool. | 64 // Step #1: Initialize the mixing thread pool. |
32 // | 65 // |
33 // TODO(johngro): make the thread pool size proportional to the maximum | 66 // TODO(johngro): make the thread pool size proportional to the maximum |
34 // number of cores available in the system. | 67 // number of cores available in the system. |
35 // | 68 // |
36 // TODO(johngro): make sure that the threads are executed at an elevated | 69 // TODO(johngro): make sure that the threads are executed at an elevated |
37 // priority, not the default priority. | 70 // priority, not the default priority. |
38 thread_pool_ = new base::SequencedWorkerPool(THREAD_POOL_SZ, THREAD_PREFIX); | 71 thread_pool_ = new base::SequencedWorkerPool(THREAD_POOL_SZ, THREAD_PREFIX); |
39 | 72 |
40 // Step #2: Instantiate all of the built-in audio output devices. | 73 // Step #2: Instantiate all of the built-in audio output devices. |
41 // | 74 // |
42 // TODO(johngro): Come up with a better way of doing this based on our | 75 // TODO(johngro): Come up with a better way of doing this based on our |
43 // platform. Right now, we just create some hardcoded default outputs and | 76 // platform. Right now, we just create some hardcoded default outputs and |
44 // leave it at that. | 77 // leave it at that. |
45 outputs_.emplace(audio::ThrottleOutput::New(this)); | 78 outputs_.emplace(audio::ThrottleOutput::New(this)); |
79 CreateAlsaOutputs(); | |
46 | 80 |
47 // Step #3: Being monitoring for plug/unplug events for pluggable audio | 81 // Step #3: Being monitoring for plug/unplug events for pluggable audio |
48 // output devices. | 82 // output devices. |
49 // | 83 // |
50 // TODO(johngro): Implement step #3. Right now, the details are behind | 84 // TODO(johngro): Implement step #3. Right now, the details are behind |
51 // hot-plug monitoring are TBD, so the feature is not implemented. | 85 // hot-plug monitoring are TBD, so the feature is not implemented. |
52 | 86 |
53 // Step #4: Attempt to initialize each of the audio outputs we have created, | 87 // Step #4: Attempt to initialize each of the audio outputs we have created, |
54 // then kick off the callback engine for each of them. | 88 // then kick off the callback engine for each of them. |
55 for (auto iter = outputs_.begin(); iter != outputs_.end(); ) { | 89 for (auto iter = outputs_.begin(); iter != outputs_.end(); ) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
141 void AudioOutputManager::ScheduleMessageLoopTask( | 175 void AudioOutputManager::ScheduleMessageLoopTask( |
142 const tracked_objects::Location& from_here, | 176 const tracked_objects::Location& from_here, |
143 const base::Closure& task) { | 177 const base::Closure& task) { |
144 DCHECK(server_); | 178 DCHECK(server_); |
145 server_->ScheduleMessageLoopTask(from_here, task); | 179 server_->ScheduleMessageLoopTask(from_here, task); |
146 } | 180 } |
147 | 181 |
148 } // namespace audio | 182 } // namespace audio |
149 } // namespace media | 183 } // namespace media |
150 } // namespace mojo | 184 } // namespace mojo |
OLD | NEW |