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
69namespace 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.
77class MEDIA_EXPORT AudioInputDevice
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