Home | History | Annotate | Download | only in media
      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 
     22 namespace media {
     23 class AudioBus;
     24 class AudioBlockFifo;
     25 class AudioOutputDevice;
     26 class AudioParameters;
     27 }
     28 
     29 namespace content {
     30 
     31 class 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.
     45 class 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