| Index: services/media/audio/audio_output.h
|
| diff --git a/services/media/audio/audio_output.h b/services/media/audio/audio_output.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0a0cce896c7d18cea0a834d5a41420ce29eed8e1
|
| --- /dev/null
|
| +++ b/services/media/audio/audio_output.h
|
| @@ -0,0 +1,174 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef SERVICES_MEDIA_AUDIO_AUDIO_OUTPUT_H_
|
| +#define SERVICES_MEDIA_AUDIO_AUDIO_OUTPUT_H_
|
| +
|
| +#include <deque>
|
| +#include <memory>
|
| +#include <set>
|
| +
|
| +#include "base/callback.h"
|
| +#include "base/synchronization/lock.h"
|
| +#include "base/threading/sequenced_worker_pool.h"
|
| +#include "mojo/services/media/common/cpp/local_time.h"
|
| +#include "services/media/audio/audio_pipe.h"
|
| +#include "services/media/audio/audio_track_impl.h"
|
| +#include "services/media/audio/fwd_decls.h"
|
| +
|
| +namespace mojo {
|
| +namespace media {
|
| +namespace audio {
|
| +
|
| +class AudioOutput {
|
| + public:
|
| + virtual ~AudioOutput();
|
| +
|
| + // AddTrack/RemoveTrack
|
| + //
|
| + // Adds or removes a track to/from the set of current set of tracks serviced
|
| + // by this output. Called only from the main message loop. Obtains the
|
| + // processing_lock and may block for the time it takes the derived class to
|
| + // run its processing task if the task is in progress when the method was
|
| + // called.
|
| + MediaResult AddTrackLink(AudioTrackToOutputLinkPtr link);
|
| + MediaResult RemoveTrackLink(const AudioTrackToOutputLinkPtr& link);
|
| +
|
| + protected:
|
| + explicit AudioOutput(AudioOutputManager* manager);
|
| +
|
| + //////////////////////////////////////////////////////////////////////////////
|
| + //
|
| + // Methods which may be implemented by derived classes to customize behavior.
|
| + //
|
| + //////////////////////////////////////////////////////////////////////////////
|
| +
|
| + // Init
|
| + //
|
| + // Called during startup on the AudioServer's main message loop thread. No
|
| + // locks are being held at this point. Derived classes should allocate their
|
| + // hardware resources and initialize any internal state. Return
|
| + // MediaResult::OK if everything is good and the output is ready to do work.
|
| + virtual MediaResult Init();
|
| +
|
| + // Cleanup
|
| + //
|
| + // Called at shutdown on the AudioServer's main message loop thread to allow
|
| + // derived classes to clean up any allocated resources. All pending
|
| + // processing callbacks have either been nerfed or run till completion. All
|
| + // AudioTrack tracks have been disconnected. No locks are being held.
|
| + virtual void Cleanup();
|
| +
|
| + // Process
|
| + //
|
| + // Called from within the context of the processing lock any time a scheduled
|
| + // processing callback fires. One callback will be automatically scheduled at
|
| + // the end of initialization. After that, derived classes are responsible for
|
| + // scheduling all subsequent callbacks to keep the engine running.
|
| + //
|
| + // Note: Process callbacks execute on one of the threads from the
|
| + // AudioOutputManager's base::SequencedWorkerPool. While successive callbacks
|
| + // may not execute on the same thread, they are guaranteed to execute in a
|
| + // serialized fashion.
|
| + virtual void Process() = 0;
|
| +
|
| + // InitializeLink
|
| + //
|
| + // Called on the AudioServer's main message loop any time a track is being
|
| + // added to this output. Outputs should allocate and initialize any
|
| + // bookkeeping they will need to perform mixing on behalf of the newly added
|
| + // track.
|
| + //
|
| + // @return MediaResult::OK if initialization succeeded, or an appropriate
|
| + // error code otherwise.
|
| + virtual MediaResult InitializeLink(const AudioTrackToOutputLinkPtr& link);
|
| +
|
| + //////////////////////////////////////////////////////////////////////////////
|
| + //
|
| + // Methods which may used by derived classes from within the context of a
|
| + // processing callback. Note; since these methods are intended to be called
|
| + // from the within a process callback, the processing_lock will always be held
|
| + // when they are called.
|
| + //
|
| +
|
| + // ScheduleCallback
|
| + //
|
| + // Schedule a processing callback at the specified absolute time on the local
|
| + // clock.
|
| + void ScheduleCallback(LocalTime when);
|
| +
|
| + // ShutdownSelf
|
| + //
|
| + // Kick off the process of shooting ourselves in the head. Note, after this
|
| + // method has been called, no new callbacks may be scheduled. As soon as the
|
| + // main message loop finds out about our shutdown request, it will complete
|
| + // the process of shutting us down, unlinking us from our tracks and calling
|
| + // the Cleanup method.
|
| + void ShutdownSelf();
|
| +
|
| + // shutting_down
|
| + //
|
| + // Check the shutting down flag. Only the base class may modify the flag, but
|
| + // derived classes are free to check it at any time.
|
| + inline bool shutting_down() const { return shutting_down_; }
|
| +
|
| + // TODO(johngro): Order this by priority. Figure out how we are going to be
|
| + // able to quickly find a track with a specific priority in order to optimize
|
| + // changes of priority. Perhaps uniquify the priorities by assigning a
|
| + // sequence number to the lower bits (avoiding collisions when assigning new
|
| + // priorities will be the trick).
|
| + //
|
| + // Right now, we have no priorities, so this is just a set of track/output
|
| + // links.
|
| + AudioTrackToOutputLinkSet links_;
|
| + AudioOutputManager* manager_;
|
| +
|
| + private:
|
| + // It's always nice when you manager is also your friend. Seriously though,
|
| + // the AudioOutputManager gets to call Init and Shutown, no one else
|
| + // (including derived classes) should be able to.
|
| + friend class AudioOutputManager;
|
| +
|
| + // Thunk used to schedule delayed processing tasks on our task_runner.
|
| + static void ProcessThunk(AudioOutputWeakPtr weak_output);
|
| +
|
| + // Called from the AudioOutputManager after an output has been created.
|
| + // Gives derived classes a chance to set up hardware, then sets up the
|
| + // machinery needed for scheduling processing tasks and schedules the first
|
| + // processing callback immediately in order to get the process running.
|
| + MediaResult Init(const AudioOutputPtr& self,
|
| + scoped_refptr<base::SequencedTaskRunner> task_runner);
|
| +
|
| + // Called from Shutdown (main message loop) and ShutdowSelf (processing
|
| + // context). Starts the process of shutdown, preventing new processing tasks
|
| + // from being scheduled, and nerfing any tasks in flight.
|
| + //
|
| + // @return true if this call just kicked off the process of shutting down,
|
| + // false otherwise.
|
| + bool BeginShutdown();
|
| +
|
| + // Called from the AudioOutputManager on the main message loop
|
| + // thread. Makes certain that the process of shutdown has started,
|
| + // synchronizes with any processing tasks which were executing at the time,
|
| + // then finishes the shutdown process by unlinking from all tracks and
|
| + // cleaning up all resources.
|
| + void Shutdown();
|
| +
|
| + base::Lock processing_lock_;
|
| + base::Lock shutdown_lock_;
|
| + scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
| + AudioOutputWeakPtr weak_self_;
|
| +
|
| + // TODO(johngro): Eliminate the shutting down flag and just use the
|
| + // task_runner_'s nullness for this test?
|
| + volatile bool shutting_down_ = false;
|
| + volatile bool shut_down_ = false;
|
| +};
|
| +
|
| +} // namespace audio
|
| +} // namespace media
|
| +} // namespace mojo
|
| +
|
| +#endif // SERVICES_MEDIA_AUDIO_AUDIO_OUTPUT_H_
|
| +
|
|
|