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

Side by Side Diff: services/media/audio/audio_output.h

Issue 1424933002: Add an initial revision of an audio server. (Closed) Base URL: https://github.com/domokit/mojo.git@change4
Patch Set: refactor MixerKernel into a class to prepare for the addition of a linear interpolation sampler 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
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 #ifndef SERVICES_MEDIA_AUDIO_AUDIO_OUTPUT_H_
6 #define SERVICES_MEDIA_AUDIO_AUDIO_OUTPUT_H_
7
8 #include <deque>
9 #include <memory>
10 #include <set>
11
12 #include "base/callback.h"
13 #include "base/synchronization/lock.h"
14 #include "base/threading/sequenced_worker_pool.h"
15 #include "mojo/services/media/common/cpp/local_time.h"
16 #include "services/media/audio/audio_pipe.h"
17 #include "services/media/audio/audio_track_impl.h"
18 #include "services/media/audio/fwd_decls.h"
19
20 namespace mojo {
21 namespace media {
22 namespace audio {
23
24 class AudioOutput {
25 public:
26 virtual ~AudioOutput();
27
28 // AddTrack/RemoveTrack
29 //
30 // Adds or removes a track to/from the set of current set of tracks serviced
31 // by this outputs. Called only from the main message loop. Obtains the
jeffbrown 2015/11/04 23:43:32 outputs -> output
johngro 2015/11/06 02:20:24 Done.
32 // processing_lock and may block for the time it takes the derrived class to
jeffbrown 2015/11/04 23:43:33 derrived -> derived
johngro 2015/11/06 02:20:24 Done.
33 // run its processing task if the task is in progress when the method was
34 // called.
jeffbrown 2015/11/04 23:43:32 In general it's safer to avoid immediately calling
johngro 2015/11/06 02:20:24 I'm not sure that I understand the question. As t
35 MediaResult AddTrackLink(AudioTrackToOutputLinkPtr link);
36 MediaResult RemoveTrackLink(const AudioTrackToOutputLinkPtr& link);
37
38 protected:
39 explicit AudioOutput(AudioOutputManager* manager);
40
41 //////////////////////////////////////////////////////////////////////////////
42 //
43 // Methods which may be implemented by derived classes to customize behavior.
44 //
45 //////////////////////////////////////////////////////////////////////////////
46
47 // Init
48 //
49 // Called during startup on the AudioServer's main message loop thread. No
50 // locks are being held at this point. Derived classes should allocate their
51 // hardware resources and initialize any internal state. Return
52 // MediaResult::OK if everything is good and the output is ready to do work.
53 virtual MediaResult Init();
jeffbrown 2015/11/04 23:43:32 Consider using a convention such as OnInit() to di
johngro 2015/11/06 02:20:24 If I had not intended for the method to be overrid
54
55 // Cleanup
56 //
57 // Called at shutdown on the AudioServer's main message loop thread to allow
58 // derived classes to clean up any allocated resources. All pending
59 // processing callbacks have either been nerfed or run till completion. All
60 // AudioTrack tracks have been disconnected. No locks are being held.
61 virtual void Cleanup();
62
63 // Process
64 //
65 // Called from within the context of the processing lock any time a scheduled
jeffbrown 2015/11/04 23:43:32 Technically you don't need a lock to guarantee ser
johngro 2015/11/06 02:20:24 The lock is not being used to guarantee serializat
66 // processing callback fires. One callback will be automatically scheduled at
67 // the end of initialization. After that, derived classes are responsible for
68 // scheduling all subsequent callbacks to keep the engine running.
69 virtual void Process() = 0;
70
71 // InitializeLink
72 //
73 // Called on the AudioServer's main message loop any time a track is being
74 // added to this output. Outputs should allocate and initialize any
75 // bookkeeping they will need to perform mixing on behalf of the newly added
76 // track.
77 //
78 // @return MediaResult::OK if initialization succeeded, or an appropriate
79 // error code otherwise.
80 virtual MediaResult InitializeLink(const AudioTrackToOutputLinkPtr& link);
81
82 //////////////////////////////////////////////////////////////////////////////
83 //
84 // Methods which may used by derived classes from within the context of a
85 // processing callback. Note; since these methods are intended to be called
86 // from the within a processing callback, the processing_lock will always be
jeffbrown 2015/11/04 23:43:32 This here suggests that these methods should be pr
johngro 2015/11/06 02:20:24 I don't understand. The context, in this case, is
87 // held when they are called.
88 //
89
90 // ScheduleCallback
91 //
92 // Schedule a processing callback at the specified absolute time on the local
93 // clock.
94 void ScheduleCallback(LocalTime when);
95
96 // ShutdownSelf
97 //
98 // Kick off the process of shooting ourselves in the head. Note, after this
99 // method has been called, no new callbacks may be scheduled. As soon as the
100 // main message loop finds out about our shutdown request, it will complete
101 // the process of shutting us down, unlinking us from our tracks and calling
102 // the Cleanup method.
103 void ShutdownSelf();
104
105 // shutting_down
106 //
107 // Check the shutting down flag. Only the base class may modify the flag, but
108 // derived classes are free to check it at any time.
109 inline bool shutting_down() const { return shutting_down_; }
110
111 // TODO(johngro): Order this by priority. Figure out how we are going to be
112 // able to quickly find a track with a specific priority in order to optimize
113 // changes of priority. Perhaps uniquify the priorities by assigning a
114 // sequence number to the lower bits (avoiding collisions when assigning new
115 // priorities will be the trick).
jeffbrown 2015/11/04 23:43:33 Could just use a heap.
johngro 2015/11/06 02:20:24 sure, I pretty much already am; right now I am usi
116 //
117 // Right now, we have no priorities, so this is just a set of track/output
118 // links.
119 AudioTrackToOutputLinkSet links_;
120 AudioOutputManager* manager_;
121
122 private:
123 // It's always nice when you manager is also your friend. Seriously though,
124 // the AudioOutputManager gets to call Init and Shutown, no one else
125 // (including derived classes) should be able to.
126 friend class AudioOutputManager;
127
128 // Thunk used to schedule delayed processing tasks on our task_runner.
129 static void ProcessThunk(AudioOutputWeakPtr weak_output);
130
131 // Called from the AudioOutputManager after an output has been created.
132 // Gives derived classes a chance to set up hardware, then sets up the
133 // machinery needed for scheduling processing tasks and schedules the first
134 // processing callback immediately in order to get the process running.
135 MediaResult Init(const AudioOutputPtr& self,
136 scoped_refptr<base::SequencedTaskRunner> task_runner);
137
138 // Called from Shutdown (main message loop) and ShutdowSelf (processing
jeffbrown 2015/11/04 23:43:32 I think it's a little weird for there to be two di
johngro 2015/11/06 02:20:24 That is how things handled now. Shutdown self pos
139 // context). Starts the process of shutdown, preventing new processing tasks
140 // from being scheduled, and nerfing any tasks in flight.
141 //
142 // @return true if this call just kicked off the process of shutting down,
143 // false otherwise.
144 bool BeginShutdown();
145
146 // Called from the AudioOutputManager on the main message loop
147 // thread. Makes certain that the process of shutdown has started,
148 // synchronizes with any processing tasks which were executing at the time,
149 // then finishes the shutdown process by unlinking from all tracks and
150 // cleaning up all resources.
151 void Shutdown();
152
153 base::Lock processing_lock_;
jeffbrown 2015/11/04 23:43:33 We won't need this lock if the processing state is
johngro 2015/11/06 02:20:24 I disagree. See my comments regarding synchroniza
154 base::Lock shutdown_lock_;
jeffbrown 2015/11/04 23:43:32 We won't need this lock is shutdown is always init
johngro 2015/11/06 02:20:24 Unfortunately, I think it is an important requirem
155 scoped_refptr<base::SequencedTaskRunner> task_runner_;
156 AudioOutputWeakPtr weak_self_;
157
158 // TODO(johngro): Eliminate the shutting down flag and just use the
159 // task_runner_'s nullness for this test?
160 volatile bool shutting_down_ = false;
161 volatile bool shut_down_ = false;
162 };
163
164 } // namespace audio
165 } // namespace media
166 } // namespace mojo
167
168 #endif // SERVICES_MEDIA_AUDIO_AUDIO_OUTPUT_H_
169
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698