• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Low-latency audio capturing class utilizing audio input stream provided
6 // by a server (browser) process by use of an IPC interface.
7 //
8 // Relationship of classes:
9 //
10 //  AudioInputController                 AudioInputDevice
11 //           ^                                  ^
12 //           |                                  |
13 //           v                  IPC             v
14 // AudioInputRendererHost  <----------->  AudioInputIPC
15 //           ^                            (AudioInputMessageFilter)
16 //           |
17 //           v
18 // AudioInputDeviceManager
19 //
20 // Transportation of audio samples from the browser to the render process
21 // is done by using shared memory in combination with a SyncSocket.
22 // The AudioInputDevice user registers an AudioInputDevice::CaptureCallback by
23 // calling Initialize().  The callback will be called with recorded audio from
24 // the underlying audio layers.
25 // The session ID is used by the AudioInputRendererHost to start the device
26 // referenced by this ID.
27 //
28 // State sequences:
29 //
30 // Start -> InitializeOnIOThread -> CreateStream ->
31 //       <- OnStreamCreated <-
32 //       -> StartOnIOThread -> PlayStream ->
33 //
34 //
35 // AudioInputDevice::Capture => low latency audio transport on audio thread =>
36 //                               |
37 // Stop --> ShutDownOnIOThread ------>  CloseStream -> Close
38 //
39 // This class depends on two threads to function:
40 //
41 // 1. An IO thread.
42 //    This thread is used to asynchronously process Start/Stop etc operations
43 //    that are available via the public interface.  The public methods are
44 //    asynchronous and simply post a task to the IO thread to actually perform
45 //    the work.
46 // 2. Audio transport thread.
47 //    Responsible for calling the CaptureCallback and feed audio samples from
48 //    the server side audio layer using a socket and shared memory.
49 //
50 // Implementation notes:
51 // - The user must call Stop() before deleting the class instance.
52 
53 #ifndef MEDIA_AUDIO_AUDIO_INPUT_DEVICE_H_
54 #define MEDIA_AUDIO_AUDIO_INPUT_DEVICE_H_
55 
56 #include <string>
57 
58 #include "base/basictypes.h"
59 #include "base/compiler_specific.h"
60 #include "base/memory/scoped_ptr.h"
61 #include "base/memory/shared_memory.h"
62 #include "media/audio/audio_device_thread.h"
63 #include "media/audio/audio_input_ipc.h"
64 #include "media/audio/audio_parameters.h"
65 #include "media/audio/scoped_task_runner_observer.h"
66 #include "media/base/audio_capturer_source.h"
67 #include "media/base/media_export.h"
68 
69 namespace media {
70 
71 // TODO(henrika): This class is based on the AudioOutputDevice class and it has
72 // many components in common. Investigate potential for re-factoring.
73 // See http://crbug.com/179597.
74 // TODO(henrika): Add support for event handling (e.g. OnStateChanged,
75 // OnCaptureStopped etc.) and ensure that we can deliver these notifications
76 // to any clients using this class.
77 class MEDIA_EXPORT AudioInputDevice
NON_EXPORTED_BASE(public AudioCapturerSource)78     : NON_EXPORTED_BASE(public AudioCapturerSource),
79       NON_EXPORTED_BASE(public AudioInputIPCDelegate),
80       NON_EXPORTED_BASE(public ScopedTaskRunnerObserver) {
81  public:
82   // NOTE: Clients must call Initialize() before using.
83   AudioInputDevice(
84       scoped_ptr<AudioInputIPC> ipc,
85       const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner);
86 
87   // AudioCapturerSource implementation.
88   virtual void Initialize(const AudioParameters& params,
89                           CaptureCallback* callback,
90                           int session_id) OVERRIDE;
91   virtual void Start() OVERRIDE;
92   virtual void Stop() OVERRIDE;
93   virtual void SetVolume(double volume) OVERRIDE;
94   virtual void SetAutomaticGainControl(bool enabled) OVERRIDE;
95 
96  protected:
97   friend class base::RefCountedThreadSafe<AudioInputDevice>;
98   virtual ~AudioInputDevice();
99 
100   // Methods called on IO thread ----------------------------------------------
101   // AudioInputIPCDelegate implementation.
102   virtual void OnStreamCreated(base::SharedMemoryHandle handle,
103                                base::SyncSocket::Handle socket_handle,
104                                int length,
105                                int total_segments) OVERRIDE;
106   virtual void OnVolume(double volume) OVERRIDE;
107   virtual void OnStateChanged(
108       AudioInputIPCDelegate::State state) OVERRIDE;
109   virtual void OnIPCClosed() OVERRIDE;
110 
111  private:
112   // Note: The ordering of members in this enum is critical to correct behavior!
113   enum State {
114     IPC_CLOSED,  // No more IPCs can take place.
115     IDLE,  // Not started.
116     CREATING_STREAM,  // Waiting for OnStreamCreated() to be called back.
117     RECORDING,  // Receiving audio data.
118   };
119 
120   // Methods called on IO thread ----------------------------------------------
121   // The following methods are tasks posted on the IO thread that needs to
122   // be executed on that thread. They interact with AudioInputMessageFilter and
123   // sends IPC messages on that thread.
124   void StartUpOnIOThread();
125   void ShutDownOnIOThread();
126   void SetVolumeOnIOThread(double volume);
127   void SetAutomaticGainControlOnIOThread(bool enabled);
128 
129   // base::MessageLoop::DestructionObserver implementation for the IO loop.
130   // If the IO loop dies before we do, we shut down the audio thread from here.
131   virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
132 
133   AudioParameters audio_parameters_;
134 
135   CaptureCallback* callback_;
136 
137   // A pointer to the IPC layer that takes care of sending requests over to
138   // the AudioInputRendererHost.  Only valid when state_ != IPC_CLOSED and must
139   // only be accessed on the IO thread.
140   scoped_ptr<AudioInputIPC> ipc_;
141 
142   // Current state (must only be accessed from the IO thread).  See comments for
143   // State enum above.
144   State state_;
145 
146   // The media session ID used to identify which input device to be started.
147   // Only modified in Initialize() and ShutDownOnIOThread().
148   int session_id_;
149 
150   // Stores the Automatic Gain Control state. Default is false.
151   // Only modified on the IO thread.
152   bool agc_is_enabled_;
153 
154   // Our audio thread callback class.  See source file for details.
155   class AudioThreadCallback;
156 
157   // In order to avoid a race between OnStreamCreated and Stop(), we use this
158   // guard to control stopping and starting the audio thread.
159   base::Lock audio_thread_lock_;
160   AudioDeviceThread audio_thread_;
161   scoped_ptr<AudioInputDevice::AudioThreadCallback> audio_callback_;
162 
163   // Temporary hack to ignore OnStreamCreated() due to the user calling Stop()
164   // so we don't start the audio thread pointing to a potentially freed
165   // |callback_|.
166   //
167   // TODO(miu): Replace this by changing AudioCapturerSource to accept the
168   // callback via Start(). See http://crbug.com/151051 for details.
169   bool stopping_hack_;
170 
171   DISALLOW_IMPLICIT_CONSTRUCTORS(AudioInputDevice);
172 };
173 
174 }  // namespace media
175 
176 #endif  // MEDIA_AUDIO_AUDIO_INPUT_DEVICE_H_
177