| 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 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 // state being used) | 38 // state being used) |
| 39 // | 39 // |
| 40 // AudioOutputDevice::Render => audio transport on audio thread => | 40 // AudioOutputDevice::Render => audio transport on audio thread => |
| 41 // | | 41 // | |
| 42 // Stop --> ShutDownOnIOThread --------> CloseStream -> Close | 42 // Stop --> ShutDownOnIOThread --------> CloseStream -> Close |
| 43 // | 43 // |
| 44 // This class utilizes several threads during its lifetime, namely: | 44 // This class utilizes several threads during its lifetime, namely: |
| 45 // 1. Creating thread. | 45 // 1. Creating thread. |
| 46 // Must be the main render thread. | 46 // Must be the main render thread. |
| 47 // 2. Control thread (may be the main render thread or another thread). | 47 // 2. Control thread (may be the main render thread or another thread). |
| 48 // The methods: Start(), Stop(), Play(), Pause(), SetVolume() | 48 // The methods Initialize(), Start(), and Stop() must be called on the same |
| 49 // must be called on the same thread. | 49 // thread. |
| 50 // 3. IO thread (internal implementation detail - not exposed to public API) | 50 // 3. IO thread (internal implementation detail - not exposed to public API) |
| 51 // The thread within which this class receives all the IPC messages and | 51 // The thread within which this class receives all the IPC messages and |
| 52 // IPC communications can only happen in this thread. | 52 // IPC communications can only happen in this thread. |
| 53 // 4. Audio transport thread (See AudioDeviceThread). | 53 // 4. Audio transport thread (See AudioDeviceThread). |
| 54 // Responsible for calling the AudioThreadCallback implementation that in | 54 // Responsible for calling the AudioThreadCallback implementation that in |
| 55 // turn calls AudioRendererSink::RenderCallback which feeds audio samples to | 55 // turn calls AudioRendererSink::RenderCallback which feeds audio samples to |
| 56 // the audio layer in the browser process using sync sockets and shared | 56 // the audio layer in the browser process using sync sockets and shared |
| 57 // memory. | 57 // memory. |
| 58 // | 58 // |
| 59 // Implementation notes: | 59 // NOTE: The user must call Stop() before deleting the class instance. |
| 60 // - The user must call Stop() before deleting the class instance. | |
| 61 | 60 |
| 62 #ifndef MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_ | 61 #ifndef MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_ |
| 63 #define MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_ | 62 #define MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_ |
| 64 | 63 |
| 65 #include <memory> | 64 #include <memory> |
| 66 #include <string> | 65 #include <string> |
| 67 | 66 |
| 68 #include "base/bind.h" | 67 #include "base/bind.h" |
| 69 #include "base/macros.h" | 68 #include "base/macros.h" |
| 70 #include "base/memory/shared_memory.h" | 69 #include "base/memory/shared_memory.h" |
| 71 #include "base/synchronization/waitable_event.h" | 70 #include "base/synchronization/waitable_event.h" |
| 71 #include "base/threading/thread_checker.h" |
| 72 #include "media/audio/audio_device_thread.h" | 72 #include "media/audio/audio_device_thread.h" |
| 73 #include "media/audio/audio_output_ipc.h" | 73 #include "media/audio/audio_output_ipc.h" |
| 74 #include "media/audio/scoped_task_runner_observer.h" | 74 #include "media/audio/scoped_task_runner_observer.h" |
| 75 #include "media/base/audio_parameters.h" | 75 #include "media/base/audio_parameters.h" |
| 76 #include "media/base/audio_renderer_sink.h" | 76 #include "media/base/audio_renderer_sink.h" |
| 77 #include "media/base/media_export.h" | 77 #include "media/base/media_export.h" |
| 78 #include "media/base/output_device_info.h" | 78 #include "media/base/output_device_info.h" |
| 79 | 79 |
| 80 namespace base { | 80 namespace base { |
| 81 class OneShotTimer; | 81 class OneShotTimer; |
| 82 } | 82 } |
| 83 | 83 |
| 84 namespace media { | 84 namespace media { |
| 85 | 85 |
| 86 class MEDIA_EXPORT AudioOutputDevice | 86 class MEDIA_EXPORT AudioOutputDevice |
| 87 : NON_EXPORTED_BASE(public AudioRendererSink), | 87 : NON_EXPORTED_BASE(public RestartableAudioRendererSink), |
| 88 NON_EXPORTED_BASE(public AudioOutputIPCDelegate), | 88 NON_EXPORTED_BASE(public AudioOutputIPCDelegate), |
| 89 NON_EXPORTED_BASE(public ScopedTaskRunnerObserver) { | 89 NON_EXPORTED_BASE(public ScopedTaskRunnerObserver) { |
| 90 public: | 90 public: |
| 91 // NOTE: Clients must call Initialize() before using. | 91 // NOTE: Clients must call Initialize() before using. |
| 92 AudioOutputDevice( | 92 AudioOutputDevice( |
| 93 std::unique_ptr<AudioOutputIPC> ipc, | 93 std::unique_ptr<AudioOutputIPC> ipc, |
| 94 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, | 94 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, |
| 95 int session_id, | 95 int session_id, |
| 96 const std::string& device_id, | 96 const std::string& device_id, |
| 97 const url::Origin& security_origin, | 97 const url::Origin& security_origin, |
| 98 base::TimeDelta authorization_timeout); | 98 base::TimeDelta authorization_timeout); |
| 99 | 99 |
| 100 // Request authorization to use the device specified in the constructor. | 100 // Request authorization to use the device specified in the constructor. |
| 101 void RequestDeviceAuthorization(); | 101 void RequestDeviceAuthorization(); |
| 102 | 102 |
| 103 // AudioRendererSink implementation. | 103 // AudioRendererSink implementation. |
| 104 void Initialize(const AudioParameters& params, | 104 void Initialize(const AudioParameters& params, |
| 105 RenderCallback* callback) override; | 105 AudioRendererSink::RenderCallback* callback) override; |
| 106 void Start() override; | 106 void Start() override; |
| 107 void Stop() override; | 107 void Stop() override; |
| 108 void Play() override; | 108 void Play() override; |
| 109 void Pause() override; | 109 void Pause() override; |
| 110 bool SetVolume(double volume) override; | 110 bool SetVolume(double volume) override; |
| 111 OutputDeviceInfo GetOutputDeviceInfo() override; | 111 OutputDeviceInfo GetOutputDeviceInfo() override; |
| 112 | 112 |
| 113 // Methods called on IO thread ---------------------------------------------- | 113 // Methods called on IO thread ---------------------------------------------- |
| 114 // AudioOutputIPCDelegate methods. | 114 // AudioOutputIPCDelegate methods. |
| 115 void OnStateChanged(AudioOutputIPCDelegateState state) override; | 115 void OnStateChanged(AudioOutputIPCDelegateState state) override; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 137 CREATING_STREAM, // Waiting for OnStreamCreated() to be called back. | 137 CREATING_STREAM, // Waiting for OnStreamCreated() to be called back. |
| 138 PAUSED, // Paused. OnStreamCreated() has been called. Can Play()/Stop(). | 138 PAUSED, // Paused. OnStreamCreated() has been called. Can Play()/Stop(). |
| 139 PLAYING, // Playing back. Can Pause()/Stop(). | 139 PLAYING, // Playing back. Can Pause()/Stop(). |
| 140 }; | 140 }; |
| 141 | 141 |
| 142 // Methods called on IO thread ---------------------------------------------- | 142 // Methods called on IO thread ---------------------------------------------- |
| 143 // The following methods are tasks posted on the IO thread that need to | 143 // The following methods are tasks posted on the IO thread that need to |
| 144 // be executed on that thread. They use AudioOutputIPC to send IPC messages | 144 // be executed on that thread. They use AudioOutputIPC to send IPC messages |
| 145 // upon state changes. | 145 // upon state changes. |
| 146 void RequestDeviceAuthorizationOnIOThread(); | 146 void RequestDeviceAuthorizationOnIOThread(); |
| 147 void CreateStreamOnIOThread(const AudioParameters& params); | 147 void CreateStreamOnIOThread(); |
| 148 void PlayOnIOThread(); | 148 void PlayOnIOThread(); |
| 149 void PauseOnIOThread(); | 149 void PauseOnIOThread(); |
| 150 void ShutDownOnIOThread(); | 150 void StopOnIOThread(); |
| 151 void SetVolumeOnIOThread(double volume); | 151 void SetVolumeOnIOThread(double volume); |
| 152 | 152 |
| 153 // Process device authorization result on the IO thread. | 153 // Process device authorization result on the IO thread. |
| 154 void ProcessDeviceAuthorizationOnIOThread( | 154 void ProcessDeviceAuthorizationOnIOThread( |
| 155 OutputDeviceStatus device_status, | 155 OutputDeviceStatus device_status, |
| 156 const media::AudioParameters& output_params, | 156 const media::AudioParameters& output_params, |
| 157 const std::string& matched_device_id, | 157 const std::string& matched_device_id, |
| 158 bool timed_out); | 158 bool timed_out); |
| 159 | 159 |
| 160 // base::MessageLoop::DestructionObserver implementation for the IO loop. | 160 // base::MessageLoop::DestructionObserver implementation for the IO loop. |
| 161 // 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. |
| 162 void WillDestroyCurrentMessageLoop() override; | 162 void WillDestroyCurrentMessageLoop() override; |
| 163 | 163 |
| 164 // Reports error to |render_callback_|. |
| 165 void ReportRenderError(); |
| 166 |
| 164 AudioParameters audio_parameters_; | 167 AudioParameters audio_parameters_; |
| 165 | 168 |
| 166 RenderCallback* callback_; | |
| 167 | |
| 168 // A pointer to the IPC layer that takes care of sending requests over to | 169 // A pointer to the IPC layer that takes care of sending requests over to |
| 169 // the AudioRendererHost. Only valid when state_ != IPC_CLOSED and must only | 170 // the AudioRendererHost. Only valid when state_ != IPC_CLOSED and must only |
| 170 // be accessed on the IO thread. | 171 // be accessed on the IO thread. |
| 171 std::unique_ptr<AudioOutputIPC> ipc_; | 172 std::unique_ptr<AudioOutputIPC> ipc_; |
| 172 | 173 |
| 173 // Current state (must only be accessed from the IO thread). See comments for | 174 // Current state (must only be accessed from the IO thread). See comments for |
| 174 // State enum above. | 175 // State enum above. |
| 175 State state_; | 176 State state_; |
| 176 | 177 |
| 177 // State of Start() calls before OnDeviceAuthorized() is called. | 178 // State of Start() calls before OnDeviceAuthorized() is called. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 188 const std::string device_id_; | 189 const std::string device_id_; |
| 189 const url::Origin security_origin_; | 190 const url::Origin security_origin_; |
| 190 | 191 |
| 191 // If |device_id_| is empty and |session_id_| is not, |matched_device_id_| is | 192 // If |device_id_| is empty and |session_id_| is not, |matched_device_id_| is |
| 192 // received in OnDeviceAuthorized(). | 193 // received in OnDeviceAuthorized(). |
| 193 std::string matched_device_id_; | 194 std::string matched_device_id_; |
| 194 | 195 |
| 195 // Our audio thread callback class. See source file for details. | 196 // Our audio thread callback class. See source file for details. |
| 196 class AudioThreadCallback; | 197 class AudioThreadCallback; |
| 197 | 198 |
| 198 // In order to avoid a race between OnStreamCreated and Stop(), we use this | 199 // This lock is used in order to: |
| 199 // guard to control stopping and starting the audio thread. | 200 // (1) Avoid a race between OnStreamCreated() and Stop(). We use this guard to |
| 200 base::Lock audio_thread_lock_; | 201 // control stopping and starting the audio thread. |
| 202 // (2) Protect |render_callback_|. |
| 203 base::Lock lock_; |
| 204 |
| 201 AudioDeviceThread audio_thread_; | 205 AudioDeviceThread audio_thread_; |
| 202 std::unique_ptr<AudioOutputDevice::AudioThreadCallback> audio_callback_; | 206 std::unique_ptr<AudioOutputDevice::AudioThreadCallback> |
| 207 audio_thread_callback_; |
| 208 |
| 209 RenderCallback* render_callback_; |
| 203 | 210 |
| 204 // Temporary hack to ignore OnStreamCreated() due to the user calling Stop() | 211 // Temporary hack to ignore OnStreamCreated() due to the user calling Stop() |
| 205 // so we don't start the audio thread pointing to a potentially freed | 212 // so we don't start the audio thread pointing to a potentially freed |
| 206 // |callback_|. | 213 // |callback_|. |
| 207 // | 214 // |
| 208 // TODO(scherkus): Replace this by changing AudioRendererSink to either accept | 215 // TODO(scherkus): Replace this by changing AudioRendererSink to either accept |
| 209 // the callback via Start(). See http://crbug.com/151051 for details. | 216 // the callback via Start(). See http://crbug.com/151051 for details. |
| 210 bool stopping_hack_; | 217 bool stopping_hack_; |
| 211 | 218 |
| 212 base::WaitableEvent did_receive_auth_; | 219 base::WaitableEvent did_receive_auth_; |
| 213 AudioParameters output_params_; | 220 AudioParameters output_params_; |
| 214 OutputDeviceStatus device_status_; | 221 OutputDeviceStatus device_status_; |
| 215 | 222 |
| 216 const base::TimeDelta auth_timeout_; | 223 const base::TimeDelta auth_timeout_; |
| 217 std::unique_ptr<base::OneShotTimer> auth_timeout_action_; | 224 std::unique_ptr<base::OneShotTimer> auth_timeout_action_; |
| 218 | 225 |
| 226 base::ThreadChecker control_thread_checker_; |
| 227 |
| 219 DISALLOW_COPY_AND_ASSIGN(AudioOutputDevice); | 228 DISALLOW_COPY_AND_ASSIGN(AudioOutputDevice); |
| 220 }; | 229 }; |
| 221 | 230 |
| 222 } // namespace media | 231 } // namespace media |
| 223 | 232 |
| 224 #endif // MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_ | 233 #endif // MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_ |
| OLD | NEW |