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 #ifndef CONTENT_RENDERER_MEDIA_WEBRTC_AUDIO_CAPTURER_H_ 6 #define CONTENT_RENDERER_MEDIA_WEBRTC_AUDIO_CAPTURER_H_ 7 8 #include <list> 9 #include <string> 10 11 #include "base/callback.h" 12 #include "base/files/file.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/synchronization/lock.h" 15 #include "base/threading/thread_checker.h" 16 #include "base/time/time.h" 17 #include "content/common/media/media_stream_options.h" 18 #include "content/renderer/media/tagged_list.h" 19 #include "media/audio/audio_input_device.h" 20 #include "media/audio/audio_power_monitor.h" 21 #include "media/base/audio_capturer_source.h" 22 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" 23 24 namespace media { 25 class AudioBus; 26 } 27 28 namespace content { 29 30 class MediaStreamAudioProcessor; 31 class MediaStreamAudioSource; 32 class WebRtcAudioDeviceImpl; 33 class WebRtcLocalAudioRenderer; 34 class WebRtcLocalAudioTrack; 35 36 // This class manages the capture data flow by getting data from its 37 // |source_|, and passing it to its |tracks_|. 38 // The threading model for this class is rather complex since it will be 39 // created on the main render thread, captured data is provided on a dedicated 40 // AudioInputDevice thread, and methods can be called either on the Libjingle 41 // thread or on the main render thread but also other client threads 42 // if an alternative AudioCapturerSource has been set. 43 class CONTENT_EXPORT WebRtcAudioCapturer 44 : public base::RefCountedThreadSafe<WebRtcAudioCapturer>, 45 NON_EXPORTED_BASE(public media::AudioCapturerSource::CaptureCallback) { 46 public: 47 // Used to construct the audio capturer. |render_view_id| specifies the 48 // render view consuming audio for capture, |render_view_id| as -1 is used 49 // by the unittests to skip creating a source via 50 // AudioDeviceFactory::NewInputDevice(), and allow injecting their own source 51 // via SetCapturerSourceForTesting() at a later state. |device_info| 52 // contains all the device information that the capturer is created for. 53 // |constraints| contains the settings for audio processing. 54 // TODO(xians): Implement the interface for the audio source and move the 55 // |constraints| to ApplyConstraints(). 56 // Called on the main render thread. 57 static scoped_refptr<WebRtcAudioCapturer> CreateCapturer( 58 int render_view_id, 59 const StreamDeviceInfo& device_info, 60 const blink::WebMediaConstraints& constraints, 61 WebRtcAudioDeviceImpl* audio_device, 62 MediaStreamAudioSource* audio_source); 63 64 65 // Add a audio track to the sinks of the capturer. 66 // WebRtcAudioDeviceImpl calls this method on the main render thread but 67 // other clients may call it from other threads. The current implementation 68 // does not support multi-thread calling. 69 // The first AddTrack will implicitly trigger the Start() of this object. 70 void AddTrack(WebRtcLocalAudioTrack* track); 71 72 // Remove a audio track from the sinks of the capturer. 73 // If the track has been added to the capturer, it must call RemoveTrack() 74 // before it goes away. 75 // Called on the main render thread or libjingle working thread. 76 void RemoveTrack(WebRtcLocalAudioTrack* track); 77 78 // Called when a stream is connecting to a peer connection. This will set 79 // up the native buffer size for the stream in order to optimize the 80 // performance for peer connection. 81 void EnablePeerConnectionMode(); 82 83 // Volume APIs used by WebRtcAudioDeviceImpl. 84 // Called on the AudioInputDevice audio thread. 85 void SetVolume(int volume); 86 int Volume() const; 87 int MaxVolume() const; 88 89 // Audio parameters utilized by the source of the audio capturer. 90 // TODO(phoglund): Think over the implications of this accessor and if we can 91 // remove it. 92 media::AudioParameters source_audio_parameters() const; 93 94 // Gets information about the paired output device. Returns true if such a 95 // device exists. 96 bool GetPairedOutputParameters(int* session_id, 97 int* output_sample_rate, 98 int* output_frames_per_buffer) const; 99 device_id()100 const std::string& device_id() const { return device_info_.device.id; } session_id()101 int session_id() const { return device_info_.session_id; } 102 103 // Stops recording audio. This method will empty its track lists since 104 // stopping the capturer will implicitly invalidate all its tracks. 105 // This method is exposed to the public because the MediaStreamAudioSource can 106 // call Stop() 107 void Stop(); 108 109 // Called by the WebAudioCapturerSource to get the audio processing params. 110 // This function is triggered by provideInput() on the WebAudio audio thread, 111 // TODO(xians): Remove after moving APM from WebRtc to Chrome. 112 void GetAudioProcessingParams(base::TimeDelta* delay, int* volume, 113 bool* key_pressed); 114 115 // Used by the unittests to inject their own source to the capturer. 116 void SetCapturerSourceForTesting( 117 const scoped_refptr<media::AudioCapturerSource>& source, 118 media::AudioParameters params); 119 120 protected: 121 friend class base::RefCountedThreadSafe<WebRtcAudioCapturer>; 122 virtual ~WebRtcAudioCapturer(); 123 124 private: 125 class TrackOwner; 126 typedef TaggedList<TrackOwner> TrackList; 127 128 WebRtcAudioCapturer(int render_view_id, 129 const StreamDeviceInfo& device_info, 130 const blink::WebMediaConstraints& constraints, 131 WebRtcAudioDeviceImpl* audio_device, 132 MediaStreamAudioSource* audio_source); 133 134 // AudioCapturerSource::CaptureCallback implementation. 135 // Called on the AudioInputDevice audio thread. 136 virtual void Capture(const media::AudioBus* audio_source, 137 int audio_delay_milliseconds, 138 double volume, 139 bool key_pressed) OVERRIDE; 140 virtual void OnCaptureError() OVERRIDE; 141 142 // Initializes the default audio capturing source using the provided render 143 // view id and device information. Return true if success, otherwise false. 144 bool Initialize(); 145 146 // SetCapturerSource() is called if the client on the source side desires to 147 // provide their own captured audio data. Client is responsible for calling 148 // Start() on its own source to have the ball rolling. 149 // Called on the main render thread. 150 void SetCapturerSource( 151 const scoped_refptr<media::AudioCapturerSource>& source, 152 media::ChannelLayout channel_layout, 153 float sample_rate); 154 155 // Starts recording audio. 156 // Triggered by AddSink() on the main render thread or a Libjingle working 157 // thread. It should NOT be called under |lock_|. 158 void Start(); 159 160 // Helper function to get the buffer size based on |peer_connection_mode_| 161 // and sample rate; 162 int GetBufferSize(int sample_rate) const; 163 164 // Used to DCHECK that we are called on the correct thread. 165 base::ThreadChecker thread_checker_; 166 167 // Protects |source_|, |audio_tracks_|, |running_|, |loopback_fifo_|, 168 // |params_| and |buffering_|. 169 mutable base::Lock lock_; 170 171 // A tagged list of audio tracks that the audio data is fed 172 // to. Tagged items need to be notified that the audio format has 173 // changed. 174 TrackList tracks_; 175 176 // The audio data source from the browser process. 177 scoped_refptr<media::AudioCapturerSource> source_; 178 179 // Cached audio constraints for the capturer. 180 blink::WebMediaConstraints constraints_; 181 182 // Audio processor doing processing like FIFO, AGC, AEC and NS. Its output 183 // data is in a unit of 10 ms data chunk. 184 scoped_refptr<MediaStreamAudioProcessor> audio_processor_; 185 186 bool running_; 187 188 int render_view_id_; 189 190 // Cached information of the device used by the capturer. 191 const StreamDeviceInfo device_info_; 192 193 // Stores latest microphone volume received in a CaptureData() callback. 194 // Range is [0, 255]. 195 int volume_; 196 197 // Flag which affects the buffer size used by the capturer. 198 bool peer_connection_mode_; 199 200 // Cache value for the audio processing params. 201 base::TimeDelta audio_delay_; 202 bool key_pressed_; 203 204 // Flag to help deciding if the data needs audio processing. 205 bool need_audio_processing_; 206 207 // Raw pointer to the WebRtcAudioDeviceImpl, which is valid for the lifetime 208 // of RenderThread. 209 WebRtcAudioDeviceImpl* audio_device_; 210 211 // Raw pointer to the MediaStreamAudioSource object that holds a reference 212 // to this WebRtcAudioCapturer. 213 // Since |audio_source_| is owned by a blink::WebMediaStreamSource object and 214 // blink guarantees that the blink::WebMediaStreamSource outlives any 215 // blink::WebMediaStreamTrack connected to the source, |audio_source_| is 216 // guaranteed to exist as long as a WebRtcLocalAudioTrack is connected to this 217 // WebRtcAudioCapturer. 218 MediaStreamAudioSource* const audio_source_; 219 220 // Audio power monitor for logging audio power level. 221 media::AudioPowerMonitor audio_power_monitor_; 222 223 // Records when the last time audio power level is logged. 224 base::TimeTicks last_audio_level_log_time_; 225 226 DISALLOW_COPY_AND_ASSIGN(WebRtcAudioCapturer); 227 }; 228 229 } // namespace content 230 231 #endif // CONTENT_RENDERER_MEDIA_WEBRTC_AUDIO_CAPTURER_H_ 232