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

Unified Diff: services/media/audio/audio_track_to_output_link.h

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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « services/media/audio/audio_track_impl.cc ('k') | services/media/audio/audio_track_to_output_link.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: services/media/audio/audio_track_to_output_link.h
diff --git a/services/media/audio/audio_track_to_output_link.h b/services/media/audio/audio_track_to_output_link.h
new file mode 100644
index 0000000000000000000000000000000000000000..f9d31ec1d2a6302540175e4c2549856553cadadf
--- /dev/null
+++ b/services/media/audio/audio_track_to_output_link.h
@@ -0,0 +1,128 @@
+// 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_TRACK_TO_OUTPUT_LINK_H_
+#define SERVICES_MEDIA_AUDIO_AUDIO_TRACK_TO_OUTPUT_LINK_H_
+
+#include <deque>
+#include <memory>
+
+#include "base/synchronization/lock.h"
+#include "services/media/audio/audio_pipe.h"
+#include "services/media/audio/fwd_decls.h"
+
+namespace mojo {
+namespace media {
+namespace audio {
+
+// AudioTrackToOutputLink is a small class which tracks the relationship between
+// an audio track and an audio output. Tracks and outputs are expected to hold
+// strong pointers to the state in the collections they use to track their
+// peers.
+//
+// When either a track or an output ceases to exist, its collection will clear
+// releasing the reference to the shared state. When the other half of the
+// relationship realizes that its peer has gone away (typically by failing to
+// promote the weak reference to its peer held in the share state object), it
+// can purge the state object strong pointer from its collection triggering the
+// final cleanup of the shared state.
+//
+// Because the final cleanup of the shared state can be triggered either from an
+// output manager mixer thread, or from the audio service's main message loop,
+// it must be safe to destruct all of the shared state from any thread in the
+// system. No assumptions may be made about threading when destructing.
+//
+// The AudioTrackToOutputLink object holds a queue of pending audio packet
+// references sourced from the AudioTrack to be rendered on the audio output.
+// The references are safe to release either from an output manager thread, or
+// from the audio service's main message loop thread (which drives track
+// behavior).
+//
+// Finally, both the Output may have a pointer to a Bookkeeping object in order
+// to manage bookkeeping tasks specific to the Track/Output relationship. The
+// following rules must be obeyed at all times...
+//
+// + Derrived classes of the Bookkeeping object created by the Output must be
+// safe to destroy either thread. During destruction, no potentially blocking
+// operations may be performed. No heavy operations (such as logging) should
+// be performed.
+// + Only the output is permitted to access the output bookkeeping. The track
+// must make no attempts to modify the bookkeeping or its pointer.
+// + Outputs must hold a strong reference to the shared link object object
+// whenever they are accessing their bookkeeping object. The link object is
+// considered to be the owner of the Bookkeeping, users must never hold a
+// naked pointer to their bookkeeping if the link could possibly destruct.
+//
+class AudioTrackToOutputLink {
+ public:
+ struct Bookkeeping {
+ virtual ~Bookkeeping();
+ };
+
+ using BookkeepingPtr = std::unique_ptr<Bookkeeping>;
+ using PacketQueue = std::deque<AudioPipe::AudioPacketRefPtr>;
+ using PacketQueuePtr = std::unique_ptr<PacketQueue>;
+
+ static AudioTrackToOutputLinkPtr New(AudioTrackImplWeakPtr track,
+ AudioOutputWeakPtr output);
+ virtual ~AudioTrackToOutputLink();
+
+ // Accessors for the track and output pointers. Automatically attempts to
+ // promote the weak pointer to a strong pointer.
+ //
+ // TODO(johngro): Given the way outputs are currently shut down, there is
+ // actually no need for the link to hold a weak pointer to output. By the
+ // time it destructs, All references to it are guaranteed to have been removed
+ // from all tracks in the context of the main event loop. Consider converting
+ // this from a weak pointer to a strong pointer.
+ AudioTrackImplPtr GetTrack() { return track_.lock(); }
+ AudioOutputPtr GetOutput() { return output_.lock(); }
+
+ // AudioTrack PendingQueue operations. Never call these from the AudioOutput.
+ void PushToPendingQueue(const AudioPipe::AudioPacketRefPtr& pkt);
+ void FlushPendingQueue();
+
+ // AudioOutput PendingQueue operations. Never call these from the AudioTrack.
+ // When consuming audio, AudioOutputs must always pair their calls to
+ // LockPendingQueueFront and UnlockPendingQueueFront, passing the pointer to
+ // the reference to the front of the queue they obtained in the process (even
+ // if the front of the queue was nullptr).
+ //
+ // Doing so ensures that AudioTracks which are attempting to flush the pending
+ // queue are forced to wait if the front of the queue is involved in a mixing
+ // operation. This, in turn, guarantees that audio packets are always
+ // returned to the user in the order which they were queued in without forcing
+ // AudioTracks to wait to queue new data if a mix operation is in progress.
+ AudioPipe::AudioPacketRefPtr LockPendingQueueFront(bool* was_flushed);
+ void UnlockPendingQueueFront(AudioPipe::AudioPacketRefPtr* pkt,
+ bool release_packet);
+
+ // Bookkeeping access.
+ //
+ BookkeepingPtr& output_bookkeeping() { return output_bookkeeping_; }
+
+ private:
+ void ReleaseQueue(const PacketQueuePtr& queue);
+
+ AudioTrackToOutputLink(AudioTrackImplWeakPtr track,
+ AudioOutputWeakPtr output);
+
+ AudioTrackImplWeakPtr track_;
+ AudioOutputWeakPtr output_;
+ BookkeepingPtr output_bookkeeping_;
+
+ base::Lock flush_lock_;
+ base::Lock pending_queue_lock_;
+ PacketQueuePtr pending_queue_;
+ bool flushed_ = true;
+#if !(defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON))
+ std::atomic<bool> flush_lock_held_;
+#endif
+};
+
+} // namespace audio
+} // namespace media
+} // namespace mojo
+
+#endif // SERVICES_MEDIA_AUDIO_AUDIO_TRACK_TO_OUTPUT_LINK_H_
« no previous file with comments | « services/media/audio/audio_track_impl.cc ('k') | services/media/audio/audio_track_to_output_link.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698