audio_output_device.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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
  3. // found in the LICENSE file.
  4. //
  5. // Audio rendering unit utilizing audio output stream provided by browser
  6. // process through IPC.
  7. //
  8. // Relationship of classes.
  9. //
  10. // AudioOutputController AudioOutputDevice
  11. // ^ ^
  12. // | |
  13. // v IPC v
  14. // MojoAudioOutputStream <---------> AudioOutputIPC (MojoAudioOutputIPC)
  15. //
  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
  18. // to generate a low latency transport. The AudioOutputDevice user registers an
  19. // AudioOutputDevice::RenderCallback at construction and will be polled by the
  20. // AudioOutputController for audio to be played out by the underlying audio
  21. // layers.
  22. //
  23. // State sequences.
  24. //
  25. // Task [IO thread] IPC [IO thread]
  26. // RequestDeviceAuthorization -> RequestDeviceAuthorizationOnIOThread ------>
  27. // RequestDeviceAuthorization ->
  28. // <- OnDeviceAuthorized <- AudioMsg_NotifyDeviceAuthorized <-
  29. //
  30. // Start -> CreateStreamOnIOThread -----> CreateStream ------>
  31. // <- OnStreamCreated <- AudioMsg_NotifyStreamCreated <-
  32. // ---> PlayOnIOThread -----------> PlayStream -------->
  33. //
  34. // Optionally Play() / Pause() sequences may occur:
  35. // Play -> PlayOnIOThread --------------> PlayStream --------->
  36. // Pause -> PauseOnIOThread ------------> PauseStream -------->
  37. // (note that Play() / Pause() sequences before
  38. // OnStreamCreated are deferred until OnStreamCreated, with the last valid
  39. // state being used)
  40. //
  41. // AudioOutputDevice::Render => audio transport on audio thread =>
  42. // |
  43. // Stop --> ShutDownOnIOThread --------> CloseStream -> Close
  44. //
  45. // This class utilizes several threads during its lifetime, namely:
  46. // 1. Creating thread.
  47. // Must be the main render thread.
  48. // 2. Control thread (may be the main render thread or another thread).
  49. // The methods: Start(), Stop(), Play(), Pause(), SetVolume()
  50. // must be called on the same thread.
  51. // 3. IO thread (internal implementation detail - not exposed to public API)
  52. // The thread within which this class receives all the IPC messages and
  53. // IPC communications can only happen in this thread.
  54. // 4. Audio transport thread (See AudioDeviceThread).
  55. // Responsible for calling the AudioOutputDeviceThreadCallback
  56. // implementation that in turn calls AudioRendererSink::RenderCallback
  57. // which feeds audio samples to the audio layer in the browser process using
  58. // sync sockets and shared memory.
  59. //
  60. // Implementation notes:
  61. // - The user must call Stop() before deleting the class instance.
  62. #ifndef MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_
  63. #define MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_
  64. #include <memory>
  65. #include <string>
  66. #include "base/bind.h"
  67. #include "base/memory/raw_ptr.h"
  68. #include "base/memory/unsafe_shared_memory_region.h"
  69. #include "base/synchronization/waitable_event.h"
  70. #include "base/thread_annotations.h"
  71. #include "base/time/time.h"
  72. #include "media/audio/audio_device_thread.h"
  73. #include "media/audio/audio_output_ipc.h"
  74. #include "media/audio/audio_sink_parameters.h"
  75. #include "media/base/audio_parameters.h"
  76. #include "media/base/audio_renderer_sink.h"
  77. #include "media/base/media_export.h"
  78. #include "media/base/output_device_info.h"
  79. namespace base {
  80. class OneShotTimer;
  81. class SingleThreadTaskRunner;
  82. }
  83. namespace media {
  84. class AudioOutputDeviceThreadCallback;
  85. class MEDIA_EXPORT AudioOutputDevice : public AudioRendererSink,
  86. public AudioOutputIPCDelegate {
  87. public:
  88. // NOTE: Clients must call Initialize() before using.
  89. AudioOutputDevice(
  90. std::unique_ptr<AudioOutputIPC> ipc,
  91. const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
  92. const AudioSinkParameters& sink_params,
  93. base::TimeDelta authorization_timeout);
  94. AudioOutputDevice(const AudioOutputDevice&) = delete;
  95. AudioOutputDevice& operator=(const AudioOutputDevice&) = delete;
  96. // Request authorization to use the device specified in the constructor.
  97. void RequestDeviceAuthorization();
  98. // AudioRendererSink implementation.
  99. void Initialize(const AudioParameters& params,
  100. RenderCallback* callback) override;
  101. void Start() override;
  102. void Stop() override;
  103. void Play() override;
  104. void Pause() override;
  105. void Flush() override;
  106. bool SetVolume(double volume) override;
  107. OutputDeviceInfo GetOutputDeviceInfo() override;
  108. void GetOutputDeviceInfoAsync(OutputDeviceInfoCB info_cb) override;
  109. bool IsOptimizedForHardwareParameters() override;
  110. bool CurrentThreadIsRenderingThread() override;
  111. // Methods called on IO thread ----------------------------------------------
  112. // AudioOutputIPCDelegate methods.
  113. void OnError() override;
  114. void OnDeviceAuthorized(OutputDeviceStatus device_status,
  115. const AudioParameters& output_params,
  116. const std::string& matched_device_id) override;
  117. void OnStreamCreated(base::UnsafeSharedMemoryRegion shared_memory_region,
  118. base::SyncSocket::ScopedHandle socket_handle,
  119. bool play_automatically) override;
  120. void OnIPCClosed() override;
  121. protected:
  122. // Magic required by ref_counted.h to avoid any code deleting the object
  123. // accidentally while there are references to it.
  124. friend class base::RefCountedThreadSafe<AudioOutputDevice>;
  125. ~AudioOutputDevice() override;
  126. private:
  127. enum StartupState {
  128. IDLE, // Authorization not requested.
  129. AUTHORIZATION_REQUESTED, // Sent (possibly completed) device
  130. // authorization request.
  131. STREAM_CREATION_REQUESTED, // Sent (possibly completed) device creation
  132. // request. Can Play()/Pause()/Stop().
  133. };
  134. // This enum is used for UMA, so the only allowed operation on this definition
  135. // is to add new states to the bottom, update kMaxValue, and update the
  136. // histogram "Media.Audio.Render.StreamCallbackError2".
  137. enum Error {
  138. kNoError = 0,
  139. kErrorDuringCreation = 1,
  140. kErrorDuringRendering = 2,
  141. kMaxValue = kErrorDuringRendering
  142. };
  143. // Methods called on IO thread ----------------------------------------------
  144. // The following methods are tasks posted on the IO thread that need to
  145. // be executed on that thread. They use AudioOutputIPC to send IPC messages
  146. // upon state changes.
  147. void RequestDeviceAuthorizationOnIOThread();
  148. void InitializeOnIOThread(const AudioParameters& params,
  149. RenderCallback* callback);
  150. void CreateStreamOnIOThread();
  151. void PlayOnIOThread();
  152. void PauseOnIOThread();
  153. void FlushOnIOThread();
  154. void ShutDownOnIOThread();
  155. void SetVolumeOnIOThread(double volume);
  156. // Process device authorization result on the IO thread.
  157. void ProcessDeviceAuthorizationOnIOThread(
  158. OutputDeviceStatus device_status,
  159. const AudioParameters& output_params,
  160. const std::string& matched_device_id,
  161. bool timed_out);
  162. void NotifyRenderCallbackOfError();
  163. OutputDeviceInfo GetOutputDeviceInfo_Signaled();
  164. void OnAuthSignal();
  165. const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
  166. AudioParameters audio_parameters_;
  167. raw_ptr<RenderCallback> callback_;
  168. // A pointer to the IPC layer that takes care of sending requests over to
  169. // the implementation. May be set to nullptr after errors.
  170. std::unique_ptr<AudioOutputIPC> ipc_;
  171. // Current state (must only be accessed from the IO thread). See comments for
  172. // State enum above.
  173. StartupState state_;
  174. // For UMA stats. May only be accessed on the IO thread.
  175. Error had_error_ = kNoError;
  176. // Last set volume.
  177. double volume_ = 1.0;
  178. // The media session ID used to identify which input device to be started.
  179. // Only used by Unified IO.
  180. base::UnguessableToken session_id_;
  181. // ID of hardware output device to be used (provided |session_id_| is zero)
  182. const std::string device_id_;
  183. // If |device_id_| is empty and |session_id_| is not, |matched_device_id_| is
  184. // received in OnDeviceAuthorized().
  185. std::string matched_device_id_;
  186. // In order to avoid a race between OnStreamCreated and Stop(), we use this
  187. // guard to control stopping and starting the audio thread.
  188. base::Lock audio_thread_lock_;
  189. std::unique_ptr<AudioOutputDeviceThreadCallback> audio_callback_;
  190. std::unique_ptr<AudioDeviceThread> audio_thread_
  191. GUARDED_BY(audio_thread_lock_);
  192. // Temporary hack to ignore OnStreamCreated() due to the user calling Stop()
  193. // so we don't start the audio thread pointing to a potentially freed
  194. // |callback_|.
  195. //
  196. // TODO(scherkus): Replace this by changing AudioRendererSink to either accept
  197. // the callback via Start(). See http://crbug.com/151051 for details.
  198. bool stopping_hack_ GUARDED_BY(audio_thread_lock_);
  199. base::WaitableEvent did_receive_auth_;
  200. AudioParameters output_params_;
  201. OutputDeviceStatus device_status_;
  202. const base::TimeDelta auth_timeout_;
  203. std::unique_ptr<base::OneShotTimer> auth_timeout_action_;
  204. // Pending callback for OutputDeviceInfo if it has not been received by the
  205. // time a call to GetGetOutputDeviceInfoAsync() is called.
  206. //
  207. // Lock for use ONLY with |pending_device_info_cb_| and |did_receive_auth_|,
  208. // if you add more usage of this lock ensure you have not added a deadlock.
  209. base::Lock device_info_lock_;
  210. OutputDeviceInfoCB pending_device_info_cb_ GUARDED_BY(device_info_lock_);
  211. };
  212. } // namespace media
  213. #endif // MEDIA_AUDIO_AUDIO_OUTPUT_DEVICE_H_