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_LOCAL_AUDIO_RENDERER_H_
6#define CONTENT_RENDERER_MEDIA_WEBRTC_LOCAL_AUDIO_RENDERER_H_
7
8#include <vector>
9
10#include "base/callback.h"
11#include "base/memory/ref_counted.h"
12#include "base/message_loop/message_loop_proxy.h"
13#include "base/synchronization/lock.h"
14#include "base/threading/thread_checker.h"
15#include "content/common/content_export.h"
16#include "content/public/renderer/media_stream_audio_sink.h"
17#include "content/renderer/media/media_stream_audio_renderer.h"
18#include "content/renderer/media/webrtc_audio_device_impl.h"
19#include "content/renderer/media/webrtc_local_audio_track.h"
20#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
21
22namespace media {
23class AudioBus;
24class AudioBlockFifo;
25class AudioOutputDevice;
26class AudioParameters;
27}
28
29namespace content {
30
31class WebRtcAudioCapturer;
32
33// WebRtcLocalAudioRenderer is a MediaStreamAudioRenderer designed for rendering
34// local audio media stream tracks,
35// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediastreamtrack
36// It also implements media::AudioRendererSink::RenderCallback to render audio
37// data provided from a WebRtcLocalAudioTrack source.
38// When the audio layer in the browser process asks for data to render, this
39// class provides the data by implementing the MediaStreamAudioSink
40// interface, i.e., we are a sink seen from the WebRtcAudioCapturer perspective.
41// TODO(henrika): improve by using similar principles as in RTCVideoRenderer
42// which register itself to the video track when the provider is started and
43// deregisters itself when it is stopped.
44// Tracking this at http://crbug.com/164813.
45class CONTENT_EXPORT WebRtcLocalAudioRenderer
46    : NON_EXPORTED_BASE(public MediaStreamAudioRenderer),
47      NON_EXPORTED_BASE(public MediaStreamAudioSink),
48      NON_EXPORTED_BASE(public media::AudioRendererSink::RenderCallback) {
49 public:
50  // Creates a local renderer and registers a capturing |source| object.
51  // The |source| is owned by the WebRtcAudioDeviceImpl.
52  // Called on the main thread.
53  WebRtcLocalAudioRenderer(const blink::WebMediaStreamTrack& audio_track,
54                           int source_render_view_id,
55                           int source_render_frame_id,
56                           int session_id,
57                           int frames_per_buffer);
58
59  // MediaStreamAudioRenderer implementation.
60  // Called on the main thread.
61  virtual void Start() OVERRIDE;
62  virtual void Stop() OVERRIDE;
63  virtual void Play() OVERRIDE;
64  virtual void Pause() OVERRIDE;
65  virtual void SetVolume(float volume) OVERRIDE;
66  virtual base::TimeDelta GetCurrentRenderTime() const OVERRIDE;
67  virtual bool IsLocalRenderer() const OVERRIDE;
68
69  const base::TimeDelta& total_render_time() const {
70    return total_render_time_;
71  }
72
73 protected:
74  virtual ~WebRtcLocalAudioRenderer();
75
76 private:
77  // MediaStreamAudioSink implementation.
78
79  // Called on the AudioInputDevice worker thread.
80  virtual void OnData(const int16* audio_data,
81                      int sample_rate,
82                      int number_of_channels,
83                      int number_of_frames) OVERRIDE;
84
85  // Called on the AudioInputDevice worker thread.
86  virtual void OnSetFormat(const media::AudioParameters& params) OVERRIDE;
87
88  // media::AudioRendererSink::RenderCallback implementation.
89  // Render() is called on the AudioOutputDevice thread and OnRenderError()
90  // on the IO thread.
91  virtual int Render(media::AudioBus* audio_bus,
92                     int audio_delay_milliseconds) OVERRIDE;
93  virtual void OnRenderError() OVERRIDE;
94
95  // Initializes and starts the |sink_| if
96  //  we have received valid |source_params_| &&
97  //  |playing_| has been set to true &&
98  //  |volume_| is not zero.
99  void MaybeStartSink();
100
101  // Sets new |source_params_| and then re-initializes and restarts |sink_|.
102  void ReconfigureSink(const media::AudioParameters& params);
103
104  // The audio track which provides data to render. Given that this class
105  // implements local loopback, the audio track is getting data from a capture
106  // instance like a selected microphone and forwards the recorded data to its
107  // sinks. The recorded data is stored in a FIFO and consumed
108  // by this class when the sink asks for new data.
109  // This class is calling MediaStreamAudioSink::AddToAudioTrack() and
110  // MediaStreamAudioSink::RemoveFromAudioTrack() to connect and disconnect
111  // with the audio track.
112  blink::WebMediaStreamTrack audio_track_;
113
114  // The render view and frame in which the audio is rendered into |sink_|.
115  const int source_render_view_id_;
116  const int source_render_frame_id_;
117  const int session_id_;
118
119  // MessageLoop associated with the single thread that performs all control
120  // tasks.  Set to the MessageLoop that invoked the ctor.
121  const scoped_refptr<base::MessageLoopProxy> message_loop_;
122
123  // The sink (destination) for rendered audio.
124  scoped_refptr<media::AudioOutputDevice> sink_;
125
126  // Contains copies of captured audio frames.
127  scoped_ptr<media::AudioBlockFifo> loopback_fifo_;
128
129  // Stores last time a render callback was received. The time difference
130  // between a new time stamp and this value can be used to derive the
131  // total render time.
132  base::TimeTicks last_render_time_;
133
134  // Keeps track of total time audio has been rendered.
135  base::TimeDelta total_render_time_;
136
137  // The audio parameters of the capture source.
138  // Must only be touched on the main thread.
139  media::AudioParameters source_params_;
140
141  // The audio parameters used by the sink.
142  // Must only be touched on the main thread.
143  media::AudioParameters sink_params_;
144
145  // Set when playing, cleared when paused.
146  bool playing_;
147
148  // Protects |loopback_fifo_|, |playing_| and |sink_|.
149  mutable base::Lock thread_lock_;
150
151  // The preferred buffer size provided via the ctor.
152  const int frames_per_buffer_;
153
154  // The preferred device id of the output device or empty for the default
155  // output device.
156  const std::string output_device_id_;
157
158  // Cache value for the volume.
159  float volume_;
160
161  // Flag to indicate whether |sink_| has been started yet.
162  bool sink_started_;
163
164  // Used to DCHECK that some methods are called on the capture audio thread.
165  base::ThreadChecker capture_thread_checker_;
166
167  DISALLOW_COPY_AND_ASSIGN(WebRtcLocalAudioRenderer);
168};
169
170}  // namespace content
171
172#endif  // CONTENT_RENDERER_MEDIA_WEBRTC_LOCAL_AUDIO_RENDERER_H_
173