audio_output_dispatcher_impl.h revision a02191e04bc25c4935f804f2c080ae28663d096d
1f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org// Use of this source code is governed by a BSD-style license that can be 3f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org// found in the LICENSE file. 4f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 5f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org// AudioOutputDispatcherImpl is an implementation of AudioOutputDispatcher. 6f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org// 7f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org// To avoid opening and closing audio devices more frequently than necessary, 8f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org// each dispatcher has a pool of inactive physical streams. A stream is closed 9f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org// only if it hasn't been used for a certain period of time (specified via the 10f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org// constructor). 118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org// 128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org 138b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#ifndef MEDIA_AUDIO_AUDIO_OUTPUT_DISPATCHER_IMPL_H_ 148b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#define MEDIA_AUDIO_AUDIO_OUTPUT_DISPATCHER_IMPL_H_ 15300f562dedd02df2f41de443c8b58ab2ceaed0f0tomhudson@google.com 16cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include <map> 17cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include <vector> 18d0c1a06cb98dd4a009dfa79e37ba6ca23a8c180btomhudson@google.com 19b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "base/basictypes.h" 2030ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "base/memory/ref_counted.h" 21b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "base/timer/timer.h" 22b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "media/audio/audio_io.h" 23894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org#include "media/audio/audio_logging.h" 24894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org#include "media/audio/audio_manager.h" 25894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org#include "media/audio/audio_output_dispatcher.h" 26f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org#include "media/audio/audio_parameters.h" 27dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com 287510b224e52b9518a8ddf7418db0e9c258f79539kkinnunennamespace media { 29cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com 30032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.comclass AudioOutputProxy; 31f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 32f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgclass MEDIA_EXPORT AudioOutputDispatcherImpl : public AudioOutputDispatcher { 33f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org public: 34f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org // |close_delay| specifies delay after the stream is idle until the audio 354b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org // device is closed. 364b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org AudioOutputDispatcherImpl(AudioManager* audio_manager, 37f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org const AudioParameters& params, 38cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com const std::string& output_device_id, 39b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const base::TimeDelta& close_delay); 40b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt 41b9119a6b563bf737e34d22f8bb96fc09a606c76fbsalomon@google.com // Opens a new physical stream if there are no pending streams in 427510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen // |idle_streams_|. Do not call Close() or Stop() if this method fails. 43894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org virtual bool OpenStream() OVERRIDE; 44894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 45b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt // If there are pending streams in |idle_streams_| then it reuses one of 46b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt // them, otherwise creates a new one. 477510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen virtual bool StartStream(AudioOutputStream::AudioSourceCallback* callback, 48f4770d7e841a34d74d7f76a33312f4c5624da831senorblanco@chromium.org AudioOutputProxy* stream_proxy) OVERRIDE; 49cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com 50f4770d7e841a34d74d7f76a33312f4c5624da831senorblanco@chromium.org // Stops the stream assigned to the specified proxy and moves it into 51f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org // |idle_streams_| for reuse by other proxies. 52f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org virtual void StopStream(AudioOutputProxy* stream_proxy) OVERRIDE; 53f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 54f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org virtual void StreamVolumeSet(AudioOutputProxy* stream_proxy, 55f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org double volume) OVERRIDE; 56f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 57f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org // Closes |idle_streams_| until the number of |idle_streams_| is equal to the 58f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org // |idle_proxies_| count. If there are no |idle_proxies_| a single stream is 59f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org // kept alive until |close_timer_| fires. 60f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org virtual void CloseStream(AudioOutputProxy* stream_proxy) OVERRIDE; 61f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 62f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org virtual void Shutdown() OVERRIDE; 63f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 64f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org private: 65b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt friend class base::RefCountedThreadSafe<AudioOutputDispatcherImpl>; 66b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual ~AudioOutputDispatcherImpl(); 67f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 68f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org // Creates a new physical output stream, opens it and pushes to 69f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org // |idle_streams_|. Returns false if the stream couldn't be created or 70f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org // opened. 71b9c95978c614e8f6bc00bdf565cff57388d8c659senorblanco@chromium.org bool CreateAndOpenStream(); 72b9c95978c614e8f6bc00bdf565cff57388d8c659senorblanco@chromium.org 73b9c95978c614e8f6bc00bdf565cff57388d8c659senorblanco@chromium.org // Closes all |idle_streams_|. 74f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org void CloseAllIdleStreams(); 75f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org // Similar to CloseAllIdleStreams(), but keeps |keep_alive| streams alive. 76f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org void CloseIdleStreams(size_t keep_alive); 77f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 78f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org size_t idle_proxies_; 79f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org std::vector<AudioOutputStream*> idle_streams_; 80f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 81f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org // When streams are stopped they're added to |idle_streams_|, if no stream is 82f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org // reused before |close_delay_| elapses |close_timer_| will run 83b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt // CloseIdleStreams(). 84b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt base::DelayTimer<AudioOutputDispatcherImpl> close_timer_; 85f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 86f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org typedef std::map<AudioOutputProxy*, AudioOutputStream*> AudioStreamMap; 87f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org AudioStreamMap proxy_to_physical_map_; 88f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 89f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org scoped_ptr<AudioLog> audio_log_; 90f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org typedef std::map<AudioOutputStream*, int> AudioStreamIDMap; 91f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org AudioStreamIDMap audio_stream_ids_; 92b9c95978c614e8f6bc00bdf565cff57388d8c659senorblanco@chromium.org int audio_stream_id_; 93b9c95978c614e8f6bc00bdf565cff57388d8c659senorblanco@chromium.org 94b9c95978c614e8f6bc00bdf565cff57388d8c659senorblanco@chromium.org DISALLOW_COPY_AND_ASSIGN(AudioOutputDispatcherImpl); 95b9c95978c614e8f6bc00bdf565cff57388d8c659senorblanco@chromium.org}; 96f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 97f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} // namespace media 98f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 99f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org#endif // MEDIA_AUDIO_AUDIO_OUTPUT_DISPATCHER_IMPL_H_ 100f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org