| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // Audio rendering unit utilizing audio output stream provided by browser | 5 // Audio rendering unit utilizing audio output stream provided by browser |
| 6 // process through IPC. | 6 // process through IPC. |
| 7 // | 7 // |
| 8 // Relationship of classes. | 8 // Relationship of classes. |
| 9 // | 9 // |
| 10 // AudioOutputController AudioOutputDevice | 10 // AudioOutputController AudioOutputDevice |
| 11 // ^ ^ | 11 // ^ ^ |
| 12 // | | | 12 // | | |
| 13 // v IPC v | 13 // v IPC v |
| 14 // AudioRendererHost <---------> AudioOutputIPC (AudioMessageFilter) | 14 // AudioRendererHost <---------> AudioOutputIPC (AudioMessageFilter) |
| 15 // | 15 // |
| 16 // Transportation of audio samples from the render to the browser process | 16 // Transportation of audio samples from the render to the browser process |
| 17 // is done by using shared memory in combination with a sync socket pair | 17 // is done by using shared memory in combination with a sync socket pair |
| 18 // to generate a low latency transport. The AudioOutputDevice user registers an | 18 // to generate a low latency transport. The AudioOutputDevice user registers an |
| 19 // AudioOutputDevice::RenderCallback at construction and will be polled by the | 19 // AudioOutputDevice::RenderCallback at construction and will be polled by the |
| 20 // AudioOutputDevice for audio to be played out by the underlying audio layers. | 20 // AudioOutputDevice for audio to be played out by the underlying audio layers. |
| 21 // | 21 // |
| 22 // State sequences. | 22 // State sequences. |
| 23 // | 23 // |
| 24 // Task [IO thread] IPC [IO thread] | 24 // Task [IO thread] IPC [IO thread] |
| 25 // RequestDeviceAuthorization -> RequestDeviceAuthorizationOnIOThread ------> |
| 26 // RequestDeviceAuthorization -> |
| 27 // <- OnDeviceAuthorized <- AudioMsg_NotifyDeviceAuthorized <- |
| 25 // | 28 // |
| 26 // Start -> CreateStreamOnIOThread -----> CreateStream ------> | 29 // Start -> CreateStreamOnIOThread -----> CreateStream ------> |
| 27 // <- OnStreamCreated <- AudioMsg_NotifyStreamCreated <- | 30 // <- OnStreamCreated <- AudioMsg_NotifyStreamCreated <- |
| 28 // ---> PlayOnIOThread -----------> PlayStream --------> | 31 // ---> PlayOnIOThread -----------> PlayStream --------> |
| 29 // | 32 // |
| 30 // Optionally Play() / Pause() sequences may occur: | 33 // Optionally Play() / Pause() / SwitchOutputDevice() sequences may occur: |
| 31 // Play -> PlayOnIOThread --------------> PlayStream ---------> | 34 // Play -> PlayOnIOThread --------------> PlayStream ---------> |
| 32 // Pause -> PauseOnIOThread ------------> PauseStream --------> | 35 // Pause -> PauseOnIOThread ------------> PauseStream --------> |
| 33 // (note that Play() / Pause() sequences before OnStreamCreated are | 36 // SwitchOutputDevice -> SwitchOutputDeviceOnIOThread -> SwitchOutputDevice -> |
| 34 // deferred until OnStreamCreated, with the last valid state being used) | 37 // <- OnOutputDeviceSwitched <- AudioMsg_NotifyOutputDeviceSwitched <- |
| 38 // (note that Play() / Pause() / SwitchOutptuDevice() sequences before |
| 39 // OnStreamCreated are deferred until OnStreamCreated, with the last valid |
| 40 // state being used) |
| 35 // | 41 // |
| 36 // AudioOutputDevice::Render => audio transport on audio thread => | 42 // AudioOutputDevice::Render => audio transport on audio thread => |
| 37 // | | 43 // | |
| 38 // Stop --> ShutDownOnIOThread --------> CloseStream -> Close | 44 // Stop --> ShutDownOnIOThread --------> CloseStream -> Close |
| 39 // | 45 // |
| 40 // This class utilizes several threads during its lifetime, namely: | 46 // This class utilizes several threads during its lifetime, namely: |
| 41 // 1. Creating thread. | 47 // 1. Creating thread. |
| 42 // Must be the main render thread. | 48 // Must be the main render thread. |
| 43 // 2. Control thread (may be the main render thread or another thread). | 49 // 2. Control thread (may be the main render thread or another thread). |
| 44 // The methods: Start(), Stop(), Play(), Pause(), SetVolume() | 50 // The methods: Start(), Stop(), Play(), Pause(), SetVolume() |
| (...skipping 12 matching lines...) Expand all Loading... |
| 57 | 63 |
| 58 #ifndef MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_ | 64 #ifndef MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_ |
| 59 #define MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_ | 65 #define MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_ |
| 60 | 66 |
| 61 #include <string> | 67 #include <string> |
| 62 | 68 |
| 63 #include "base/basictypes.h" | 69 #include "base/basictypes.h" |
| 64 #include "base/bind.h" | 70 #include "base/bind.h" |
| 65 #include "base/memory/scoped_ptr.h" | 71 #include "base/memory/scoped_ptr.h" |
| 66 #include "base/memory/shared_memory.h" | 72 #include "base/memory/shared_memory.h" |
| 73 #include "base/synchronization/waitable_event.h" |
| 67 #include "media/audio/audio_device_thread.h" | 74 #include "media/audio/audio_device_thread.h" |
| 68 #include "media/audio/audio_output_ipc.h" | 75 #include "media/audio/audio_output_ipc.h" |
| 69 #include "media/audio/audio_parameters.h" | 76 #include "media/audio/audio_parameters.h" |
| 70 #include "media/audio/scoped_task_runner_observer.h" | 77 #include "media/audio/scoped_task_runner_observer.h" |
| 71 #include "media/base/audio_renderer_sink.h" | 78 #include "media/base/audio_renderer_sink.h" |
| 72 #include "media/base/media_export.h" | 79 #include "media/base/media_export.h" |
| 73 #include "media/base/output_device.h" | 80 #include "media/base/output_device.h" |
| 74 | 81 |
| 75 namespace media { | 82 namespace media { |
| 76 | 83 |
| 77 class MEDIA_EXPORT AudioOutputDevice | 84 class MEDIA_EXPORT AudioOutputDevice |
| 78 : NON_EXPORTED_BASE(public AudioRendererSink), | 85 : NON_EXPORTED_BASE(public AudioRendererSink), |
| 79 NON_EXPORTED_BASE(public AudioOutputIPCDelegate), | 86 NON_EXPORTED_BASE(public AudioOutputIPCDelegate), |
| 80 NON_EXPORTED_BASE(public OutputDevice), | 87 NON_EXPORTED_BASE(public OutputDevice), |
| 81 NON_EXPORTED_BASE(public ScopedTaskRunnerObserver) { | 88 NON_EXPORTED_BASE(public ScopedTaskRunnerObserver) { |
| 82 public: | 89 public: |
| 83 // NOTE: Clients must call Initialize() before using. | 90 // NOTE: Clients must call Initialize() before using. |
| 84 AudioOutputDevice( | 91 AudioOutputDevice( |
| 85 scoped_ptr<AudioOutputIPC> ipc, | 92 scoped_ptr<AudioOutputIPC> ipc, |
| 86 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner); | 93 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, |
| 94 int session_id, |
| 95 const std::string& device_id, |
| 96 const url::Origin& security_origin); |
| 87 | 97 |
| 88 // Initialize the stream using |session_id|, which is used for the browser | 98 // Request authorization to use the device specified in the constructor. |
| 89 // to select the correct input device. | 99 void RequestDeviceAuthorization(); |
| 90 void InitializeWithSessionId(const AudioParameters& params, | |
| 91 RenderCallback* callback, | |
| 92 int session_id); | |
| 93 | 100 |
| 94 // AudioRendererSink implementation. | 101 // AudioRendererSink implementation. |
| 95 void Initialize(const AudioParameters& params, | 102 void Initialize(const AudioParameters& params, |
| 96 RenderCallback* callback) override; | 103 RenderCallback* callback) override; |
| 97 void Start() override; | 104 void Start() override; |
| 98 void Stop() override; | 105 void Stop() override; |
| 99 void Play() override; | 106 void Play() override; |
| 100 void Pause() override; | 107 void Pause() override; |
| 101 bool SetVolume(double volume) override; | 108 bool SetVolume(double volume) override; |
| 102 OutputDevice* GetOutputDevice() override; | 109 OutputDevice* GetOutputDevice() override; |
| 103 | 110 |
| 104 // OutputDevice implementation | 111 // OutputDevice implementation |
| 105 void SwitchOutputDevice(const std::string& device_id, | 112 void SwitchOutputDevice(const std::string& device_id, |
| 106 const GURL& security_origin, | 113 const url::Origin& security_origin, |
| 107 const SwitchOutputDeviceCB& callback) override; | 114 const SwitchOutputDeviceCB& callback) override; |
| 115 AudioParameters GetOutputParameters() override; |
| 108 | 116 |
| 109 // Methods called on IO thread ---------------------------------------------- | 117 // Methods called on IO thread ---------------------------------------------- |
| 110 // AudioOutputIPCDelegate methods. | 118 // AudioOutputIPCDelegate methods. |
| 111 void OnStateChanged(AudioOutputIPCDelegateState state) override; | 119 void OnStateChanged(AudioOutputIPCDelegateState state) override; |
| 120 void OnDeviceAuthorized(bool success, |
| 121 const media::AudioParameters& output_params) override; |
| 112 void OnStreamCreated(base::SharedMemoryHandle handle, | 122 void OnStreamCreated(base::SharedMemoryHandle handle, |
| 113 base::SyncSocket::Handle socket_handle, | 123 base::SyncSocket::Handle socket_handle, |
| 114 int length) override; | 124 int length) override; |
| 115 void OnOutputDeviceSwitched(int request_id, | 125 void OnOutputDeviceSwitched(SwitchOutputDeviceResult result) override; |
| 116 SwitchOutputDeviceResult result) override; | |
| 117 void OnIPCClosed() override; | 126 void OnIPCClosed() override; |
| 118 | 127 |
| 119 protected: | 128 protected: |
| 120 // Magic required by ref_counted.h to avoid any code deleting the object | 129 // Magic required by ref_counted.h to avoid any code deleting the object |
| 121 // accidentally while there are references to it. | 130 // accidentally while there are references to it. |
| 122 friend class base::RefCountedThreadSafe<AudioOutputDevice>; | 131 friend class base::RefCountedThreadSafe<AudioOutputDevice>; |
| 123 ~AudioOutputDevice() override; | 132 ~AudioOutputDevice() override; |
| 124 | 133 |
| 125 private: | 134 private: |
| 126 // Note: The ordering of members in this enum is critical to correct behavior! | 135 // Note: The ordering of members in this enum is critical to correct behavior! |
| 127 enum State { | 136 enum State { |
| 128 IPC_CLOSED, // No more IPCs can take place. | 137 IPC_CLOSED, // No more IPCs can take place. |
| 129 IDLE, // Not started. | 138 IDLE, // Not started. |
| 139 AUTHORIZING, // Sent device authorization request, waiting for reply. |
| 140 AUTHORIZED, // Successful device authorization received. |
| 130 CREATING_STREAM, // Waiting for OnStreamCreated() to be called back. | 141 CREATING_STREAM, // Waiting for OnStreamCreated() to be called back. |
| 131 PAUSED, // Paused. OnStreamCreated() has been called. Can Play()/Stop(). | 142 PAUSED, // Paused. OnStreamCreated() has been called. Can Play()/Stop(). |
| 132 PLAYING, // Playing back. Can Pause()/Stop(). | 143 PLAYING, // Playing back. Can Pause()/Stop(). |
| 133 }; | 144 }; |
| 134 | 145 |
| 135 // Methods called on IO thread ---------------------------------------------- | 146 // Methods called on IO thread ---------------------------------------------- |
| 136 // The following methods are tasks posted on the IO thread that need to | 147 // The following methods are tasks posted on the IO thread that need to |
| 137 // be executed on that thread. They use AudioOutputIPC to send IPC messages | 148 // be executed on that thread. They use AudioOutputIPC to send IPC messages |
| 138 // upon state changes. | 149 // upon state changes. |
| 150 void RequestDeviceAuthorizationOnIOThread(); |
| 139 void CreateStreamOnIOThread(const AudioParameters& params); | 151 void CreateStreamOnIOThread(const AudioParameters& params); |
| 140 void PlayOnIOThread(); | 152 void PlayOnIOThread(); |
| 141 void PauseOnIOThread(); | 153 void PauseOnIOThread(); |
| 142 void ShutDownOnIOThread(); | 154 void ShutDownOnIOThread(); |
| 143 void SetVolumeOnIOThread(double volume); | 155 void SetVolumeOnIOThread(double volume); |
| 144 void SwitchOutputDeviceOnIOThread(const std::string& device_id, | 156 void SwitchOutputDeviceOnIOThread(const std::string& device_id, |
| 145 const GURL& security_origin, | 157 const url::Origin& security_origin, |
| 146 const SwitchOutputDeviceCB& callback); | 158 const SwitchOutputDeviceCB& callback); |
| 147 | 159 |
| 148 // base::MessageLoop::DestructionObserver implementation for the IO loop. | 160 // base::MessageLoop::DestructionObserver implementation for the IO loop. |
| 149 // If the IO loop dies before we do, we shut down the audio thread from here. | 161 // If the IO loop dies before we do, we shut down the audio thread from here. |
| 150 void WillDestroyCurrentMessageLoop() override; | 162 void WillDestroyCurrentMessageLoop() override; |
| 151 | 163 |
| 152 void SetCurrentSwitchRequest(const SwitchOutputDeviceCB& callback); | 164 void SetCurrentSwitchRequest(const SwitchOutputDeviceCB& callback, |
| 165 const std::string& device_id, |
| 166 const url::Origin& security_origin); |
| 167 void SetOutputParams(const media::AudioParameters& output_params); |
| 153 | 168 |
| 154 AudioParameters audio_parameters_; | 169 AudioParameters audio_parameters_; |
| 155 | 170 |
| 156 RenderCallback* callback_; | 171 RenderCallback* callback_; |
| 157 | 172 |
| 158 // A pointer to the IPC layer that takes care of sending requests over to | 173 // A pointer to the IPC layer that takes care of sending requests over to |
| 159 // the AudioRendererHost. Only valid when state_ != IPC_CLOSED and must only | 174 // the AudioRendererHost. Only valid when state_ != IPC_CLOSED and must only |
| 160 // be accessed on the IO thread. | 175 // be accessed on the IO thread. |
| 161 scoped_ptr<AudioOutputIPC> ipc_; | 176 scoped_ptr<AudioOutputIPC> ipc_; |
| 162 | 177 |
| 163 // Current state (must only be accessed from the IO thread). See comments for | 178 // Current state (must only be accessed from the IO thread). See comments for |
| 164 // State enum above. | 179 // State enum above. |
| 165 State state_; | 180 State state_; |
| 166 | 181 |
| 182 // State of Start() calls before OnDeviceAuthorized() is called. |
| 183 bool start_on_authorized_; |
| 184 |
| 167 // State of Play() / Pause() calls before OnStreamCreated() is called. | 185 // State of Play() / Pause() calls before OnStreamCreated() is called. |
| 168 bool play_on_start_; | 186 bool play_on_start_; |
| 169 | 187 |
| 170 // The media session ID used to identify which input device to be started. | 188 // The media session ID used to identify which input device to be started. |
| 171 // Only used by Unified IO. | 189 // Only used by Unified IO. |
| 172 int session_id_; | 190 int session_id_; |
| 173 | 191 |
| 192 // ID of hardware output device to be used (provided session_id_ is zero) |
| 193 std::string device_id_; |
| 194 url::Origin security_origin_; |
| 195 |
| 174 // Our audio thread callback class. See source file for details. | 196 // Our audio thread callback class. See source file for details. |
| 175 class AudioThreadCallback; | 197 class AudioThreadCallback; |
| 176 | 198 |
| 177 // In order to avoid a race between OnStreamCreated and Stop(), we use this | 199 // In order to avoid a race between OnStreamCreated and Stop(), we use this |
| 178 // guard to control stopping and starting the audio thread. | 200 // guard to control stopping and starting the audio thread. |
| 179 base::Lock audio_thread_lock_; | 201 base::Lock audio_thread_lock_; |
| 180 AudioDeviceThread audio_thread_; | 202 AudioDeviceThread audio_thread_; |
| 181 scoped_ptr<AudioOutputDevice::AudioThreadCallback> audio_callback_; | 203 scoped_ptr<AudioOutputDevice::AudioThreadCallback> audio_callback_; |
| 182 | 204 |
| 183 // Temporary hack to ignore OnStreamCreated() due to the user calling Stop() | 205 // Temporary hack to ignore OnStreamCreated() due to the user calling Stop() |
| 184 // so we don't start the audio thread pointing to a potentially freed | 206 // so we don't start the audio thread pointing to a potentially freed |
| 185 // |callback_|. | 207 // |callback_|. |
| 186 // | 208 // |
| 187 // TODO(scherkus): Replace this by changing AudioRendererSink to either accept | 209 // TODO(scherkus): Replace this by changing AudioRendererSink to either accept |
| 188 // the callback via Start(). See http://crbug.com/151051 for details. | 210 // the callback via Start(). See http://crbug.com/151051 for details. |
| 189 bool stopping_hack_; | 211 bool stopping_hack_; |
| 190 | 212 |
| 191 int current_switch_request_id_; | |
| 192 SwitchOutputDeviceCB current_switch_callback_; | 213 SwitchOutputDeviceCB current_switch_callback_; |
| 214 std::string current_switch_device_id_; |
| 215 url::Origin current_switch_security_origin_; |
| 216 bool switch_output_device_on_start_; |
| 217 |
| 218 base::WaitableEvent did_set_output_params_; |
| 219 media::AudioParameters output_params_; |
| 193 | 220 |
| 194 DISALLOW_COPY_AND_ASSIGN(AudioOutputDevice); | 221 DISALLOW_COPY_AND_ASSIGN(AudioOutputDevice); |
| 195 }; | 222 }; |
| 196 | 223 |
| 197 } // namespace media | 224 } // namespace media |
| 198 | 225 |
| 199 #endif // MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_ | 226 #endif // MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_ |
| OLD | NEW |