• 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 #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/memory/ref_counted.h"
13 #include "base/synchronization/lock.h"
14 #include "base/threading/thread_checker.h"
15 #include "base/time/time.h"
16 #include "content/renderer/media/tagged_list.h"
17 #include "content/renderer/media/webrtc_audio_device_impl.h"
18 #include "media/audio/audio_input_device.h"
19 #include "media/base/audio_capturer_source.h"
20 
21 namespace media {
22 class AudioBus;
23 }
24 
25 namespace content {
26 
27 class WebRtcLocalAudioRenderer;
28 class WebRtcLocalAudioTrack;
29 
30 // This class manages the capture data flow by getting data from its
31 // |source_|, and passing it to its |tracks_|.
32 // It allows clients to inject their own capture data source by calling
33 // SetCapturerSource().
34 // The threading model for this class is rather complex since it will be
35 // created on the main render thread, captured data is provided on a dedicated
36 // AudioInputDevice thread, and methods can be called either on the Libjingle
37 // thread or on the main render thread but also other client threads
38 // if an alternative AudioCapturerSource has been set.
39 class CONTENT_EXPORT WebRtcAudioCapturer
40     : public base::RefCountedThreadSafe<WebRtcAudioCapturer>,
41       NON_EXPORTED_BASE(public media::AudioCapturerSource::CaptureCallback) {
42  public:
43   // Use to construct the audio capturer.
44   // Called on the main render thread.
45   static scoped_refptr<WebRtcAudioCapturer> CreateCapturer();
46 
47   // Creates and configures the default audio capturing source using the
48   // provided audio parameters.  |render_view_id| specifies the render view
49   // consuming audio for capture.  |session_id| is passed to the browser to
50   // decide which device to use.  |device_id| is used to identify which device
51   // the capturer is created for.  Called on the main render thread.
52   bool Initialize(int render_view_id,
53                   media::ChannelLayout channel_layout,
54                   int sample_rate,
55                   int buffer_size,
56                   int session_id,
57                   const std::string& device_id,
58                   int paired_output_sample_rate,
59                   int paired_output_frames_per_buffer,
60                   int effects);
61 
62   // Add a audio track to the sinks of the capturer.
63   // WebRtcAudioDeviceImpl calls this method on the main render thread but
64   // other clients may call it from other threads. The current implementation
65   // does not support multi-thread calling.
66   // The first AddTrack will implicitly trigger the Start() of this object.
67   // Called on the main render thread or libjingle working thread.
68   void AddTrack(WebRtcLocalAudioTrack* track);
69 
70   // Remove a audio track from the sinks of the capturer.
71   // If the track has been added to the capturer, it  must call RemoveTrack()
72   // before it goes away.
73   // Called on the main render thread or libjingle working thread.
74   void RemoveTrack(WebRtcLocalAudioTrack* track);
75 
76   // SetCapturerSource() is called if the client on the source side desires to
77   // provide their own captured audio data. Client is responsible for calling
78   // Start() on its own source to have the ball rolling.
79   // Called on the main render thread.
80   void SetCapturerSource(
81       const scoped_refptr<media::AudioCapturerSource>& source,
82       media::ChannelLayout channel_layout,
83       float sample_rate,
84       int effects);
85 
86   // Called when a stream is connecting to a peer connection. This will set
87   // up the native buffer size for the stream in order to optimize the
88   // performance for peer connection.
89   void EnablePeerConnectionMode();
90 
91   // Volume APIs used by WebRtcAudioDeviceImpl.
92   // Called on the AudioInputDevice audio thread.
93   void SetVolume(int volume);
94   int Volume() const;
95   int MaxVolume() const;
96 
is_recording()97   bool is_recording() const { return running_; }
98 
99   // Audio parameters utilized by the audio capturer. Can be utilized by
100   // a local renderer to set up a renderer using identical parameters as the
101   // capturer.
102   // TODO(phoglund): This accessor is inherently unsafe since the returned
103   // parameters can become outdated at any time. Think over the implications
104   // of this accessor and if we can remove it.
105   media::AudioParameters audio_parameters() const;
106 
107   // Gets information about the paired output device. Returns true if such a
108   // device exists.
109   bool GetPairedOutputParameters(int* session_id,
110                                  int* output_sample_rate,
111                                  int* output_frames_per_buffer) const;
112 
device_id()113   const std::string& device_id() const { return device_id_; }
session_id()114   int session_id() const { return session_id_; }
115 
116   // Stops recording audio. This method will empty its track lists since
117   // stopping the capturer will implicitly invalidate all its tracks.
118   // This method is exposed to the public because the media stream track can
119   // call Stop() on its source.
120   void Stop();
121 
122   // Called by the WebAudioCapturerSource to get the audio processing params.
123   // This function is triggered by provideInput() on the WebAudio audio thread,
124   // TODO(xians): Remove after moving APM from WebRtc to Chrome.
125   void GetAudioProcessingParams(base::TimeDelta* delay, int* volume,
126                                 bool* key_pressed);
127 
128  protected:
129   friend class base::RefCountedThreadSafe<WebRtcAudioCapturer>;
130   WebRtcAudioCapturer();
131   virtual ~WebRtcAudioCapturer();
132 
133  private:
134   class TrackOwner;
135   typedef TaggedList<TrackOwner> TrackList;
136 
137   // AudioCapturerSource::CaptureCallback implementation.
138   // Called on the AudioInputDevice audio thread.
139   virtual void Capture(media::AudioBus* audio_source,
140                        int audio_delay_milliseconds,
141                        double volume,
142                        bool key_pressed) OVERRIDE;
143   virtual void OnCaptureError() OVERRIDE;
144 
145   // Reconfigures the capturer with a new capture parameters.
146   // Must be called without holding the lock.
147   void Reconfigure(int sample_rate, media::ChannelLayout channel_layout,
148                    int effects);
149 
150   // Starts recording audio.
151   // Triggered by AddSink() on the main render thread or a Libjingle working
152   // thread. It should NOT be called under |lock_|.
153   void Start();
154 
155   // Helper function to get the buffer size based on |peer_connection_mode_|
156   // and sample rate;
157   int GetBufferSize(int sample_rate) const;
158 
159   // Used to DCHECK that we are called on the correct thread.
160   base::ThreadChecker thread_checker_;
161 
162   // Protects |source_|, |audio_tracks_|, |running_|, |loopback_fifo_|,
163   // |params_| and |buffering_|.
164   mutable base::Lock lock_;
165 
166   // A tagged list of audio tracks that the audio data is fed
167   // to. Tagged items need to be notified that the audio format has
168   // changed.
169   TrackList tracks_;
170 
171   // The audio data source from the browser process.
172   scoped_refptr<media::AudioCapturerSource> source_;
173 
174   // Cached audio parameters for output.
175   media::AudioParameters params_;
176 
177   bool running_;
178 
179   int render_view_id_;
180 
181   // Cached value for the hardware native buffer size, used when
182   // |peer_connection_mode_| is set to false.
183   int hardware_buffer_size_;
184 
185   // The media session ID used to identify which input device to be started by
186   // the browser.
187   int session_id_;
188 
189   // The device this capturer is given permission to use.
190   std::string device_id_;
191 
192   // Stores latest microphone volume received in a CaptureData() callback.
193   // Range is [0, 255].
194   int volume_;
195 
196   // Flag which affects the buffer size used by the capturer.
197   bool peer_connection_mode_;
198 
199   int output_sample_rate_;
200   int output_frames_per_buffer_;
201 
202   // Cache value for the audio processing params.
203   base::TimeDelta audio_delay_;
204   bool key_pressed_;
205 
206   DISALLOW_COPY_AND_ASSIGN(WebRtcAudioCapturer);
207 };
208 
209 }  // namespace content
210 
211 #endif  // CONTENT_RENDERER_MEDIA_WEBRTC_AUDIO_CAPTURER_H_
212