blob: 623b55c448cca0fc28b170536304ffe99cfed9ea [file] [log] [blame]
// 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_SERVER_IMPL_H_
#define SERVICES_MEDIA_AUDIO_AUDIO_SERVER_IMPL_H_
#include <list>
#include <set>
#include "base/callback.h"
#include "base/synchronization/lock.h"
#include "base/task_runner.h"
#include "mojo/services/media/audio/interfaces/audio_server.mojom.h"
#include "mojo/services/media/audio/interfaces/audio_track.mojom.h"
#include "services/media/audio/audio_output_manager.h"
#include "services/media/audio/fwd_decls.h"
#include "services/media/common/media_pipe_base.h"
namespace mojo {
namespace media {
namespace audio {
class AudioServerImpl : public AudioServer {
public:
AudioServerImpl();
~AudioServerImpl() override;
void Initialize();
// AudioServer
void CreateTrack(mojo::InterfaceRequest<AudioTrack> track) override;
// Called (indirectly) by AudioOutputs to schedule the callback for a
// MediaPacked which was queued to an AudioTrack via. a media pipe.
//
// TODO(johngro): This bouncing through thread contexts is inefficient and
// will increase the latency requirements for clients (its going to take them
// some extra time to discover that their media has been completely consumed).
// When mojo exposes a way to safely invoke interface method callbacks from
// threads other than the thread which executed the method itself, we will
// want to switch to creating the callback message directly, instead of
// indirecting through the server.
void SchedulePacketCleanup(MediaPipeBase::MediaPacketStatePtr state);
// Schedule a closure to run on the server's main message loop.
void ScheduleMessageLoopTask(const tracked_objects::Location& from_here,
const base::Closure& task) {
DCHECK(task_runner_);
bool success = task_runner_->PostTask(from_here, task);
DCHECK(success);
}
// Removes a track from the set of active tracks.
void RemoveTrack(AudioTrackImplPtr track) {
size_t removed;
removed = tracks_.erase(track);
DCHECK(removed);
}
// Accessor for our encapsulated output manager.
AudioOutputManager& GetOutputManager() { return output_manager_; }
private:
using CleanupQueue = std::list<MediaPipeBase::MediaPacketStatePtr>;
void Shutdown();
void DoPacketCleanup();
// A reference to our message loop's task runner. Allows us to post events to
// be handled by our main application thread from things like the output
// manager's thread pool.
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
// State for dealing with outputs.
AudioOutputManager output_manager_;
// State for dealing with tracks.
std::set<AudioTrackImplPtr> tracks_;
// State for dealing with cleanup tasks.
base::Lock cleanup_queue_lock_;
std::unique_ptr<CleanupQueue> cleanup_queue_;
bool cleanup_scheduled_ = false;
bool shutting_down_ = false;
base::Closure cleanup_closure_;
};
} // namespace audio
} // namespace media
} // namespace mojo
#endif // SERVICES_MEDIA_AUDIO_AUDIO_SERVER_IMPL_H_