OLD | NEW |
---|---|
(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 #ifndef SERVICES_MEDIA_AUDIO_AUDIO_OUTPUT_MANAGER_H_ | |
6 #define SERVICES_MEDIA_AUDIO_AUDIO_OUTPUT_MANAGER_H_ | |
7 | |
8 #include <set> | |
9 | |
10 #include "base/synchronization/lock.h" | |
11 #include "base/threading/sequenced_worker_pool.h" | |
12 #include "mojo/services/media/common/interfaces/media_common.mojom.h" | |
13 #include "mojo/services/media/common/interfaces/media_pipe.mojom.h" | |
14 #include "services/media/audio/audio_output.h" | |
15 #include "services/media/audio/fwd_decls.h" | |
16 | |
17 namespace mojo { | |
18 namespace media { | |
19 namespace audio { | |
20 | |
21 class AudioOutputManager { | |
22 public: | |
23 explicit AudioOutputManager(AudioServerImpl* server); | |
24 ~AudioOutputManager(); | |
25 | |
26 // Initialize the output manager. Called from the service implementation, | |
27 // once, at startup time. Should... | |
28 // | |
29 // 1) Initialize the mixing thread pool. | |
30 // 2) Instantiate all of the built-in audio output devices. | |
31 // 3) Being monitoring for plug/unplug events for pluggable audio output | |
32 // devices. | |
33 MediaResult Init(); | |
34 | |
35 // Blocking call. Called by the service, once, when it is time to shutdown | |
36 // the service implementation. While this function is blocking, it must never | |
37 // block for long. Our process is going away; this is our last chance to | |
38 // perform a clean shutdown. If an unclean shutdown must be performed in | |
39 // order to implode in a timely fashion, so be it. | |
40 // | |
41 // Shutdown must be idempotent, and safe to call from the output manager's | |
42 // destructor, although it should never be necessary to do so. If the | |
43 // shutdown called from the destructor has to do real work, something has gone | |
44 // Very Seriously Wrong. | |
jeffbrown
2015/11/04 23:43:33
Instead of this comment, maybe just make it blow u
johngro
2015/11/06 02:20:25
I already have some DCHECK protection for the idem
| |
45 void Shutdown(); | |
46 | |
47 // Select the initial set of outputs for a track which has just been | |
48 // configured. | |
49 void SelectOutputsForTrack(AudioTrackImplPtr track); | |
50 | |
51 // Schedule a closure to run on our encapsulating server's main message loop. | |
52 void ScheduleMessageLoopTask(const tracked_objects::Location& from_here, | |
53 const base::Closure& task); | |
54 | |
55 // Shutdown the specified audio output and remove it from the set of active | |
56 // outputs. | |
57 void ShutdownOutput(AudioOutputPtr output); | |
58 | |
59 private: | |
60 // TODO(johngro): A SequencedWorkerPool currently seems to be as close to what | |
61 // we want which we can currently get using the chrome/mojo framework. Things | |
62 // which are missing and will eventually need to be addressed include... | |
63 // | |
64 // 1) Threads are created on the fly, as needed. We really want to be able to | |
65 // spin up the proper number of threads at pool creation time. Audio | |
66 // mixing is very timing sensitive... If we are in a situation where we | |
67 // have not hit the max number of threads in the pool, and we need to spin | |
68 // up a thread in order to mix, we *really* do not want to have to wait to | |
69 // create the thread at the OS level before we can mix some audio. The | |
70 // thread needs to already be ready to go. | |
71 // 2) Threads in the pool are created with default priority. Audio mixing | |
72 // threads will need to be created with elevated priority. | |
73 // 3) It is currently unclear if explicitly scheduling tasks with delays will | |
74 // be sufficient for the audio mixer. We really would like to be able to | |
75 // have tasks fire when some handle abstraction becomes signalled. This | |
76 // will let us implement mixing not only with open loop timing, but also | |
77 // with events which can come from device drivers. Note: this seems to be | |
78 // an issue with the TaskRunner architecture in general, not the | |
79 // SequencedWorkerPool in specific. | |
80 // 4) The resolution of posted delayed tasks may hinder the low latency goals | |
81 // of the system. Being able to know the underlying achievable resolution | |
82 // of dispatching delayed tasks is a minimum requirement. From that, we | |
83 // can compute our worst case overhead which can be communicated to the | |
84 // user and will have an effect on overall latency. Hitting something on | |
85 // the order of 10s of microseconds is what we really should be shooting | |
86 // for here. Single milliseconds is probably too coarse. | |
87 // 5) Not a requirement, but a sure-would-be-nice-to-have... Scheduling | |
88 // delayed tasks using absolute times. Having to schedule using delta | |
89 // times from now means that we need to take the time it takes to schedule | |
90 // the task (along with its jitter) into account when scheduling. This can | |
91 // lead to additional, undesirable, latency. | |
92 scoped_refptr<base::SequencedWorkerPool> thread_pool_; | |
jeffbrown
2015/11/04 23:43:33
Alternately if the number of audio outputs is smal
johngro
2015/11/06 02:20:24
Acknowledged.
We may end up at this point. Per-ou
| |
93 | |
94 // A pointer to the server which encapsulates us. It is not possible for this | |
95 // pointer to be bad while we still exist. | |
96 AudioServerImpl* server_; | |
97 | |
98 // Our set of currently active audio output instances. | |
99 // | |
100 // Contents of the output set must only be manipulated on the main message | |
101 // loop thread, so no synchronization should be needed. | |
102 AudioOutputSet outputs_; | |
103 }; | |
104 | |
105 } // namespace audio | |
106 } // namespace media | |
107 } // namespace mojo | |
108 | |
109 #endif // SERVICES_MEDIA_AUDIO_AUDIO_OUTPUT_MANAGER_H_ | |
OLD | NEW |