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 process by use of an IPC interface. 7 // 8 // Relationship of classes: 9 // 10 // AudioInputController AudioInputDevice 11 // ^ ^ 12 // | | 13 // v IPC v 14 // MojoAudioInputStream <-----------> AudioInputIPC 15 // ^ (MojoAudioInputIPC) 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 RenderFrameAudioInputStreamFactory to start 26 // the device referenced by this ID. 27 // 28 // State sequences: 29 // 30 // Start -> CreateStream -> 31 // <- OnStreamCreated <- 32 // -> RecordStream -> 33 // 34 // AudioInputDevice::Capture => low latency audio transport on audio thread => 35 // 36 // Stop -> CloseStream -> Close 37 // 38 // This class depends on the audio transport thread. That thread is responsible 39 // for calling the CaptureCallback and feeding it audio samples from the server 40 // side audio layer using a socket and shared memory. 41 // 42 // Implementation notes: 43 // - The user must call Stop() before deleting the class instance. 44 45 #ifndef MEDIA_AUDIO_AUDIO_INPUT_DEVICE_H_ 46 #define MEDIA_AUDIO_AUDIO_INPUT_DEVICE_H_ 47 48 #include <memory> 49 #include <string> 50 51 #include "base/compiler_specific.h" 52 #include "base/macros.h" 53 #include "base/memory/read_only_shared_memory_region.h" 54 #include "base/optional.h" 55 #include "base/sequence_checker.h" 56 #include "base/threading/platform_thread.h" 57 #include "base/time/time.h" 58 #include "media/audio/alive_checker.h" 59 #include "media/audio/audio_device_thread.h" 60 #include "media/audio/audio_input_ipc.h" 61 #include "media/base/audio_capturer_source.h" 62 #include "media/base/audio_parameters.h" 63 #include "media/base/media_export.h" 64 65 namespace media { 66 67 class MEDIA_EXPORT AudioInputDevice : public AudioCapturerSource, 68 public AudioInputIPCDelegate { 69 public: 70 enum Purpose : int8_t { kUserInput, kLoopback }; 71 72 // NOTE: Clients must call Initialize() before using. 73 // |enable_uma| controls logging of UMA stats. It is used to ensure that 74 // stats are not logged for mirroring service streams. 75 AudioInputDevice(std::unique_ptr<AudioInputIPC> ipc, Purpose purpose); 76 77 // AudioCapturerSource implementation. 78 void Initialize(const AudioParameters& params, 79 CaptureCallback* callback) override; 80 void Start() override; 81 void Stop() override; 82 void SetVolume(double volume) override; 83 void SetAutomaticGainControl(bool enabled) override; 84 void SetOutputDeviceForAec(const std::string& output_device_id) override; 85 86 private: 87 friend class base::RefCountedThreadSafe<AudioInputDevice>; 88 89 // Our audio thread callback class. See source file for details. 90 class AudioThreadCallback; 91 92 // Note: The ordering of members in this enum is critical to correct behavior! 93 enum State { 94 IPC_CLOSED, // No more IPCs can take place. 95 IDLE, // Not started. 96 CREATING_STREAM, // Waiting for OnStreamCreated() to be called back. 97 RECORDING, // Receiving audio data. 98 }; 99 100 // This enum is used for UMA, so the only allowed operation on this definition 101 // is to add new states to the bottom, update kMaxValue, and update the 102 // histogram "Media.Audio.Capture.StreamCallbackError2". 103 enum Error { 104 kNoError = 0, 105 kErrorDuringCreation = 1, 106 kErrorDuringCapture = 2, 107 kMaxValue = kErrorDuringCapture 108 }; 109 110 ~AudioInputDevice() override; 111 112 // AudioInputIPCDelegate implementation. 113 void OnStreamCreated(base::ReadOnlySharedMemoryRegion shared_memory_region, 114 base::SyncSocket::ScopedHandle socket_handle, 115 bool initially_muted) override; 116 void OnError() override; 117 void OnMuted(bool is_muted) override; 118 void OnIPCClosed() override; 119 120 // This is called by |alive_checker_| if it detects that the input stream is 121 // dead. 122 void DetectedDeadInputStream(); 123 124 AudioParameters audio_parameters_; 125 126 const base::ThreadPriority thread_priority_; 127 128 const bool enable_uma_; 129 130 CaptureCallback* callback_; 131 132 // A pointer to the IPC layer that takes care of sending requests over to 133 // the stream implementation. Only valid when state_ != IPC_CLOSED. 134 std::unique_ptr<AudioInputIPC> ipc_; 135 136 // Current state. See comments for State enum above. 137 State state_; 138 139 // For UMA stats. May only be accessed on the IO thread. 140 Error had_error_ = kNoError; 141 142 // Stores the Automatic Gain Control state. Default is false. 143 bool agc_is_enabled_; 144 145 // Checks regularly that the input stream is alive and notifies us if it 146 // isn't by calling DetectedDeadInputStream(). Must outlive |audio_callback_|. 147 std::unique_ptr<AliveChecker> alive_checker_; 148 149 std::unique_ptr<AudioInputDevice::AudioThreadCallback> audio_callback_; 150 std::unique_ptr<AudioDeviceThread> audio_thread_; 151 152 SEQUENCE_CHECKER(sequence_checker_); 153 154 // Cache the output device used for AEC in case it's called before the stream 155 // is created. 156 base::Optional<std::string> output_device_id_for_aec_; 157 158 DISALLOW_IMPLICIT_CONSTRUCTORS(AudioInputDevice); 159 }; 160 161 } // namespace media 162 163 #endif // MEDIA_AUDIO_AUDIO_INPUT_DEVICE_H_ 164