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
24namespace media {
25class AudioBus;
26}
27
28namespace content {
29
30class MediaStreamAudioProcessor;
31class MediaStreamAudioSource;
32class WebRtcAudioDeviceImpl;
33class WebRtcLocalAudioRenderer;
34class 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.
43class 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
100  const std::string& device_id() const { return device_info_.device.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