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

Side by Side Diff: services/media/audio/audio_output_manager.cc

Issue 1424933002: Add an initial revision of an audio server. (Closed) Base URL: https://github.com/domokit/mojo.git@change4
Patch Set: fix issues discovered with initial preflight Created 5 years, 1 month 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
« no previous file with comments | « services/media/audio/audio_output_manager.h ('k') | services/media/audio/audio_pipe.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include <string>
6
7 #include "services/media/audio/audio_output.h"
8 #include "services/media/audio/audio_output_manager.h"
9 #include "services/media/audio/audio_server_impl.h"
10 #include "services/media/audio/audio_track_to_output_link.h"
11 #include "services/media/audio/platform/generic/throttle_output.h"
12
13 namespace mojo {
14 namespace media {
15 namespace audio {
16
17 static constexpr size_t THREAD_POOL_SZ = 2;
18 static const std::string THREAD_PREFIX("AudioMixer");
19
20 AudioOutputManager::AudioOutputManager(AudioServerImpl* server)
21 : server_(server) {
22 }
23
24 AudioOutputManager::~AudioOutputManager() {
25 Shutdown();
26 DCHECK_EQ(outputs_.size(), 0u);
27 DCHECK(!thread_pool_);
28 }
29
30 MediaResult AudioOutputManager::Init() {
31 // Step #1: Initialize the mixing thread pool.
32 //
33 // TODO(johngro): make the thread pool size proportional to the maximum
34 // number of cores available in the system.
35 //
36 // TODO(johngro): make sure that the threads are executed at an elevated
37 // priority, not the default priority.
38 thread_pool_ = new base::SequencedWorkerPool(THREAD_POOL_SZ, THREAD_PREFIX);
39
40 // Step #2: Instantiate all of the built-in audio output devices.
41 //
42 // 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
44 // leave it at that.
45 outputs_.emplace(audio::ThrottleOutput::New(this));
46
47 // Step #3: Being monitoring for plug/unplug events for pluggable audio
48 // output devices.
49 //
50 // TODO(johngro): Implement step #3. Right now, the details are behind
51 // hot-plug monitoring are TBD, so the feature is not implemented.
52
53 // Step #4: Attempt to initialize each of the audio outputs we have created,
54 // then kick off the callback engine for each of them.
55 for (auto iter = outputs_.begin(); iter != outputs_.end(); ) {
56 const AudioOutputPtr& output = *iter;
57 auto tmp = iter++;
58 DCHECK(output);
59
60 // Create a sequenced task runner for this output. It will be used by the
61 // output to schedule jobs (such as mixing) on the thread pool.
62 scoped_refptr<base::SequencedTaskRunner> task_runner =
63 thread_pool_->GetSequencedTaskRunnerWithShutdownBehavior(
64 thread_pool_->GetSequenceToken(),
65 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
66
67 MediaResult res = output->Init(output, task_runner);
68 if (res != MediaResult::OK) {
69 // TODO(johngro): Probably should log something about this, assuming that
70 // the output has not already.
71 outputs_.erase(tmp);
72 }
73 }
74
75 return MediaResult::OK;
76 }
77
78 void AudioOutputManager::Shutdown() {
79 // Are we already shutdown (or were we never successfully initialized?)
80 if (thread_pool_ == nullptr) {
81 DCHECK_EQ(outputs_.size(), 0u);
82 return;
83 }
84
85 // Step #1: Stop monitoringing plug/unplug events. We are shutting down and
86 // no longer care about outputs coming and going.
87 //
88 // TODO(johngro): Implement step #1. Right now, the details are behind
89 // hot-plug monitoring are TBD, so the feature is not implemented.
90
91 // Step #2: Shut down each currently active output in the system. It is
92 // possible for this to take a bit of time as outputs release their hardware,
93 // but it should not take long.
94 for (const auto& output_ptr : outputs_) {
95 output_ptr->Shutdown();
96 }
97 outputs_.clear();
98
99 // Step #3: Shutdown and release our thread pool. Since we have shut down all
100 // of our outputs, any pending tasks left in the task runner are now no-ops,
101 // so it does not matter that the task runner is going to cancel them all
102 // (instead of blocking) when we shut it down.
103 thread_pool_->Shutdown();
104 thread_pool_ = nullptr;
105 }
106
107 void AudioOutputManager::ShutdownOutput(AudioOutputPtr output) {
108 // No one should be calling this method if we have been shut down (or never
109 // successfully started).
110 DCHECK(thread_pool_);
111
112 auto iter = outputs_.find(output);
113 if (iter != outputs_.end()) {
114 output->Shutdown();
115 outputs_.erase(iter);
116 }
117 }
118
119 void AudioOutputManager::SelectOutputsForTrack(AudioTrackImplPtr track) {
120 // TODO(johngro): Someday, base this on policy. For now, every track gets
121 // assigned to every output in the system.
122 DCHECK(track);
123
124 // TODO(johngro): Add some way to assert that we are executing on the main
125 // message loop thread.
126
127 for (auto output : outputs_) {
128 auto link = AudioTrackToOutputLink::New(track, output);
129 DCHECK(output);
130 DCHECK(link);
131
132 // If we cannot add this link to the output, it's because the output is in
133 // the process of shutting down (we didn't want to hang out with that guy
134 // anyway)
135 if (output->AddTrackLink(link) == MediaResult::OK) {
136 track->AddOutput(link);
137 }
138 }
139 }
140
141 void AudioOutputManager::ScheduleMessageLoopTask(
142 const tracked_objects::Location& from_here,
143 const base::Closure& task) {
144 DCHECK(server_);
145 server_->ScheduleMessageLoopTask(from_here, task);
146 }
147
148 } // namespace audio
149 } // namespace media
150 } // namespace mojo
OLDNEW
« no previous file with comments | « services/media/audio/audio_output_manager.h ('k') | services/media/audio/audio_pipe.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698