Chromium Code Reviews| 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); |
| 87 | 94 |
| 88 // Initialize the stream using |session_id|, which is used for the browser | 95 // Create AudioOutputDevice associated with a given output device. |
| 89 // to select the correct input device. | 96 AudioOutputDevice( |
| 90 void InitializeWithSessionId(const AudioParameters& params, | 97 scoped_ptr<AudioOutputIPC> ipc, |
| 91 RenderCallback* callback, | 98 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, |
| 92 int session_id); | 99 int session_id, |
| 100 const std::string& device_id, | |
| 101 const GURL& security_origin); | |
| 102 | |
| 103 // Request authorization to use the device specified in the constructor. | |
| 104 void RequestDeviceAuthorization(); | |
| 93 | 105 |
| 94 // AudioRendererSink implementation. | 106 // AudioRendererSink implementation. |
| 95 void Initialize(const AudioParameters& params, | 107 void Initialize(const AudioParameters& params, |
| 96 RenderCallback* callback) override; | 108 RenderCallback* callback) override; |
| 97 void Start() override; | 109 void Start() override; |
| 98 void Stop() override; | 110 void Stop() override; |
| 99 void Play() override; | 111 void Play() override; |
| 100 void Pause() override; | 112 void Pause() override; |
| 101 bool SetVolume(double volume) override; | 113 bool SetVolume(double volume) override; |
| 102 OutputDevice* GetOutputDevice() override; | 114 OutputDevice* GetOutputDevice() override; |
| 103 | 115 |
| 104 // OutputDevice implementation | 116 // OutputDevice implementation |
| 105 void SwitchOutputDevice(const std::string& device_id, | 117 void SwitchOutputDevice(const std::string& device_id, |
| 106 const GURL& security_origin, | 118 const GURL& security_origin, |
| 107 const SwitchOutputDeviceCB& callback) override; | 119 const SwitchOutputDeviceCB& callback) override; |
| 120 AudioParameters GetOutputParameters() override; | |
| 108 | 121 |
| 109 // Methods called on IO thread ---------------------------------------------- | 122 // Methods called on IO thread ---------------------------------------------- |
| 110 // AudioOutputIPCDelegate methods. | 123 // AudioOutputIPCDelegate methods. |
| 111 void OnStateChanged(AudioOutputIPCDelegateState state) override; | 124 void OnStateChanged(AudioOutputIPCDelegateState state) override; |
| 125 void OnDeviceAuthorized(bool success, | |
| 126 const media::AudioParameters& output_params) override; | |
| 112 void OnStreamCreated(base::SharedMemoryHandle handle, | 127 void OnStreamCreated(base::SharedMemoryHandle handle, |
| 113 base::SyncSocket::Handle socket_handle, | 128 base::SyncSocket::Handle socket_handle, |
| 114 int length) override; | 129 int length) override; |
| 115 void OnOutputDeviceSwitched(int request_id, | 130 void OnOutputDeviceSwitched( |
| 116 SwitchOutputDeviceResult result) override; | 131 SwitchOutputDeviceResult result, |
| 132 const media::AudioParameters& output_params) override; | |
| 117 void OnIPCClosed() override; | 133 void OnIPCClosed() override; |
| 118 | 134 |
| 119 protected: | 135 protected: |
| 120 // Magic required by ref_counted.h to avoid any code deleting the object | 136 // Magic required by ref_counted.h to avoid any code deleting the object |
| 121 // accidentally while there are references to it. | 137 // accidentally while there are references to it. |
| 122 friend class base::RefCountedThreadSafe<AudioOutputDevice>; | 138 friend class base::RefCountedThreadSafe<AudioOutputDevice>; |
| 123 ~AudioOutputDevice() override; | 139 ~AudioOutputDevice() override; |
| 124 | 140 |
| 125 private: | 141 private: |
| 126 // Note: The ordering of members in this enum is critical to correct behavior! | 142 // Note: The ordering of members in this enum is critical to correct behavior! |
| 127 enum State { | 143 enum State { |
| 128 IPC_CLOSED, // No more IPCs can take place. | 144 IPC_CLOSED, // No more IPCs can take place. |
| 129 IDLE, // Not started. | 145 IDLE, // Not started. |
| 146 NOT_AUTHORIZED, // Failed device authorization received. | |
|
DaleCurtis
2015/09/12 01:17:19
Should we just reuse IPC_CLOSED for this state?
Guido Urdaneta
2015/09/14 11:35:48
Done.
| |
| 147 AUTHORIZING, // Sent device authorization request, waiting for reply. | |
| 148 AUTHORIZED, // Successful device authorization received. | |
| 130 CREATING_STREAM, // Waiting for OnStreamCreated() to be called back. | 149 CREATING_STREAM, // Waiting for OnStreamCreated() to be called back. |
| 131 PAUSED, // Paused. OnStreamCreated() has been called. Can Play()/Stop(). | 150 PAUSED, // Paused. OnStreamCreated() has been called. Can Play()/Stop(). |
| 132 PLAYING, // Playing back. Can Pause()/Stop(). | 151 PLAYING, // Playing back. Can Pause()/Stop(). |
| 133 }; | 152 }; |
| 134 | 153 |
| 135 // Methods called on IO thread ---------------------------------------------- | 154 // Methods called on IO thread ---------------------------------------------- |
| 136 // The following methods are tasks posted on the IO thread that need to | 155 // 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 | 156 // be executed on that thread. They use AudioOutputIPC to send IPC messages |
| 138 // upon state changes. | 157 // upon state changes. |
| 158 void RequestDeviceAuthorizationOnIOThread(); | |
| 139 void CreateStreamOnIOThread(const AudioParameters& params); | 159 void CreateStreamOnIOThread(const AudioParameters& params); |
| 140 void PlayOnIOThread(); | 160 void PlayOnIOThread(); |
| 141 void PauseOnIOThread(); | 161 void PauseOnIOThread(); |
| 142 void ShutDownOnIOThread(); | 162 void ShutDownOnIOThread(); |
| 143 void SetVolumeOnIOThread(double volume); | 163 void SetVolumeOnIOThread(double volume); |
| 144 void SwitchOutputDeviceOnIOThread(const std::string& device_id, | 164 void SwitchOutputDeviceOnIOThread(const std::string& device_id, |
| 145 const GURL& security_origin, | 165 const GURL& security_origin, |
| 146 const SwitchOutputDeviceCB& callback); | 166 const SwitchOutputDeviceCB& callback); |
| 147 | 167 |
| 148 // base::MessageLoop::DestructionObserver implementation for the IO loop. | 168 // 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. | 169 // If the IO loop dies before we do, we shut down the audio thread from here. |
| 150 void WillDestroyCurrentMessageLoop() override; | 170 void WillDestroyCurrentMessageLoop() override; |
| 151 | 171 |
| 152 void SetCurrentSwitchRequest(const SwitchOutputDeviceCB& callback); | 172 void SetCurrentSwitchRequest(const SwitchOutputDeviceCB& callback, |
| 173 const std::string& device_id, | |
| 174 const GURL& security_origin); | |
| 175 void SetOutputParams(const media::AudioParameters& output_params); | |
| 153 | 176 |
| 154 AudioParameters audio_parameters_; | 177 AudioParameters audio_parameters_; |
| 155 | 178 |
| 156 RenderCallback* callback_; | 179 RenderCallback* callback_; |
| 157 | 180 |
| 158 // A pointer to the IPC layer that takes care of sending requests over to | 181 // 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 | 182 // the AudioRendererHost. Only valid when state_ != IPC_CLOSED and must only |
| 160 // be accessed on the IO thread. | 183 // be accessed on the IO thread. |
| 161 scoped_ptr<AudioOutputIPC> ipc_; | 184 scoped_ptr<AudioOutputIPC> ipc_; |
| 162 | 185 |
| 163 // Current state (must only be accessed from the IO thread). See comments for | 186 // Current state (must only be accessed from the IO thread). See comments for |
| 164 // State enum above. | 187 // State enum above. |
| 165 State state_; | 188 State state_; |
| 166 | 189 |
| 190 // State of Start() calls before OnDeviceAuthorized() is called. | |
| 191 bool start_on_authorized_; | |
| 192 | |
| 167 // State of Play() / Pause() calls before OnStreamCreated() is called. | 193 // State of Play() / Pause() calls before OnStreamCreated() is called. |
| 168 bool play_on_start_; | 194 bool play_on_start_; |
| 169 | 195 |
| 170 // The media session ID used to identify which input device to be started. | 196 // The media session ID used to identify which input device to be started. |
| 171 // Only used by Unified IO. | 197 // Only used by Unified IO. |
| 172 int session_id_; | 198 int session_id_; |
| 173 | 199 |
| 200 // ID of hardware output device to be used (provided session_id_ is zero) | |
| 201 std::string device_id_; | |
| 202 GURL security_origin_; | |
| 203 | |
| 174 // Our audio thread callback class. See source file for details. | 204 // Our audio thread callback class. See source file for details. |
| 175 class AudioThreadCallback; | 205 class AudioThreadCallback; |
| 176 | 206 |
| 177 // In order to avoid a race between OnStreamCreated and Stop(), we use this | 207 // In order to avoid a race between OnStreamCreated and Stop(), we use this |
| 178 // guard to control stopping and starting the audio thread. | 208 // guard to control stopping and starting the audio thread. |
| 179 base::Lock audio_thread_lock_; | 209 base::Lock audio_thread_lock_; |
| 180 AudioDeviceThread audio_thread_; | 210 AudioDeviceThread audio_thread_; |
| 181 scoped_ptr<AudioOutputDevice::AudioThreadCallback> audio_callback_; | 211 scoped_ptr<AudioOutputDevice::AudioThreadCallback> audio_callback_; |
| 182 | 212 |
| 183 // Temporary hack to ignore OnStreamCreated() due to the user calling Stop() | 213 // 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 | 214 // so we don't start the audio thread pointing to a potentially freed |
| 185 // |callback_|. | 215 // |callback_|. |
| 186 // | 216 // |
| 187 // TODO(scherkus): Replace this by changing AudioRendererSink to either accept | 217 // TODO(scherkus): Replace this by changing AudioRendererSink to either accept |
| 188 // the callback via Start(). See http://crbug.com/151051 for details. | 218 // the callback via Start(). See http://crbug.com/151051 for details. |
| 189 bool stopping_hack_; | 219 bool stopping_hack_; |
| 190 | 220 |
| 191 int current_switch_request_id_; | |
| 192 SwitchOutputDeviceCB current_switch_callback_; | 221 SwitchOutputDeviceCB current_switch_callback_; |
| 222 std::string current_switch_device_id_; | |
| 223 GURL current_switch_security_origin_; | |
| 224 bool switch_output_device_on_start_; | |
| 225 | |
| 226 base::WaitableEvent did_set_output_params_; | |
| 227 media::AudioParameters output_params_; | |
| 193 | 228 |
| 194 DISALLOW_COPY_AND_ASSIGN(AudioOutputDevice); | 229 DISALLOW_COPY_AND_ASSIGN(AudioOutputDevice); |
| 195 }; | 230 }; |
| 196 | 231 |
| 197 } // namespace media | 232 } // namespace media |
| 198 | 233 |
| 199 #endif // MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_ | 234 #endif // MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_ |
| OLD | NEW |