15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/webrtc_audio_renderer.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/strings/stringprintf.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/audio_device_factory.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/renderer/media/media_stream_dispatcher.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/webrtc_audio_device_impl.h"
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/renderer/media/webrtc_logging.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/renderer/render_frame_impl.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/audio/audio_output_device.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/audio/audio_parameters.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/audio/sample_rates.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/libjingle/source/talk/media/base/audiorenderer.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/win/windows_version.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/audio/win/core_audio_util_win.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// We add a UMA histogram measuring the execution time of the Render() method
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// every |kNumCallbacksBetweenRenderTimeHistograms| callback. Assuming 10ms
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// between each callback leads to one UMA update each 100ms.
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kNumCallbacksBetweenRenderTimeHistograms = 10;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// This is a simple wrapper class that's handed out to users of a shared
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// WebRtcAudioRenderer instance.  This class maintains the per-user 'playing'
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// and 'started' states to avoid problems related to incorrect usage which
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// might violate the implementation assumptions inside WebRtcAudioRenderer
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// (see the play reference count).
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class SharedAudioRenderer : public MediaStreamAudioRenderer {
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Callback definition for a callback that is called when when Play(), Pause()
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // or SetVolume are called (whenever the internal |playing_state_| changes).
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef base::Callback<
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      void(const scoped_refptr<webrtc::MediaStreamInterface>&,
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)           WebRtcAudioRenderer::PlayingState*)> OnPlayStateChanged;
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SharedAudioRenderer(
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const scoped_refptr<MediaStreamAudioRenderer>& delegate,
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const scoped_refptr<webrtc::MediaStreamInterface>& media_stream,
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const OnPlayStateChanged& on_play_state_changed)
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : delegate_(delegate), media_stream_(media_stream), started_(false),
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        on_play_state_changed_(on_play_state_changed) {
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(!on_play_state_changed_.is_null());
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(media_stream_.get());
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) protected:
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~SharedAudioRenderer() {
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DVLOG(1) << __FUNCTION__;
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    Stop();
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void Start() OVERRIDE {
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (started_)
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    started_ = true;
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    delegate_->Start();
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void Play() OVERRIDE {
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(started_);
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (playing_state_.playing())
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    playing_state_.set_playing(true);
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    on_play_state_changed_.Run(media_stream_, &playing_state_);
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void Pause() OVERRIDE {
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(started_);
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!playing_state_.playing())
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    playing_state_.set_playing(false);
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    on_play_state_changed_.Run(media_stream_, &playing_state_);
9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void Stop() OVERRIDE {
9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!started_)
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    Pause();
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    started_ = false;
9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    delegate_->Stop();
10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void SetVolume(float volume) OVERRIDE {
10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(volume >= 0.0f && volume <= 1.0f);
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    playing_state_.set_volume(volume);
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    on_play_state_changed_.Run(media_stream_, &playing_state_);
10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual base::TimeDelta GetCurrentRenderTime() const OVERRIDE {
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return delegate_->GetCurrentRenderTime();
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual bool IsLocalRenderer() const OVERRIDE {
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return delegate_->IsLocalRenderer();
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::ThreadChecker thread_checker_;
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const scoped_refptr<MediaStreamAudioRenderer> delegate_;
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const scoped_refptr<webrtc::MediaStreamInterface> media_stream_;
12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool started_;
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WebRtcAudioRenderer::PlayingState playing_state_;
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  OnPlayStateChanged on_play_state_changed_;
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Returns either AudioParameters::NO_EFFECTS or AudioParameters::DUCKING
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// depending on whether or not an input element is currently open with
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// ducking enabled.
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint GetCurrentDuckingFlag(int render_frame_id) {
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RenderFrameImpl* const frame =
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      RenderFrameImpl::FromRoutingID(render_frame_id);
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MediaStreamDispatcher* const dispatcher = frame ?
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      frame->GetMediaStreamDispatcher() : NULL;
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (dispatcher && dispatcher->IsAudioDuckingActive()) {
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return media::AudioParameters::DUCKING;
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return media::AudioParameters::NO_EFFECTS;
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Helper method to get platform specific optimal buffer size.
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint GetOptimalBufferSize(int sample_rate, int hardware_buffer_size) {
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Use native hardware buffer size as default. On Windows, we strive to open
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // up using this native hardware buffer size to achieve best
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // possible performance and to ensure that no FIFO is needed on the browser
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // side to match the client request. That is why there is no #if case for
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Windows below.
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int frames_per_buffer = hardware_buffer_size;
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_LINUX) || defined(OS_MACOSX)
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // On Linux and MacOS, the low level IO implementations on the browser side
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // supports all buffer size the clients want. We use the native peer
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // connection buffer size (10ms) to achieve best possible performance.
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  frames_per_buffer = sample_rate / 100;
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#elif defined(OS_ANDROID)
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(henrika): Keep tuning this scheme and espcicially for low-latency
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // cases. Might not be possible to come up with the perfect solution using
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the render side only.
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int frames_per_10ms = sample_rate / 100;
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (frames_per_buffer < 2 * frames_per_10ms) {
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Examples of low-latency frame sizes and the resulting |buffer_size|:
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    //  Nexus 7     : 240 audio frames => 2*480 = 960
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    //  Nexus 10    : 256              => 2*441 = 882
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    //  Galaxy Nexus: 144              => 2*441 = 882
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    frames_per_buffer = 2 * frames_per_10ms;
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DVLOG(1) << "Low-latency output detected on Android";
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DVLOG(1) << "Using sink output buffer size: " << frames_per_buffer;
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return frames_per_buffer;
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)WebRtcAudioRenderer::WebRtcAudioRenderer(
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const scoped_refptr<webrtc::MediaStreamInterface>& media_stream,
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int source_render_view_id,
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int source_render_frame_id,
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int session_id,
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int sample_rate,
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int frames_per_buffer)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : state_(UNINITIALIZED),
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      source_render_view_id_(source_render_view_id),
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      source_render_frame_id_(source_render_frame_id),
18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      session_id_(session_id),
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      media_stream_(media_stream),
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      source_(NULL),
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      play_ref_count_(0),
19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      start_ref_count_(0),
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      audio_delay_milliseconds_(0),
19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      fifo_delay_milliseconds_(0),
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      sink_params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   media::CHANNEL_LAYOUT_STEREO, sample_rate, 16,
197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   frames_per_buffer,
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   GetCurrentDuckingFlag(source_render_frame_id)),
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      render_callback_count_(0) {
200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  WebRtcLogMessage(base::StringPrintf(
201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "WAR::WAR. source_render_view_id=%d"
202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ", session_id=%d, sample_rate=%d, frames_per_buffer=%d, effects=%i",
203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      source_render_view_id,
204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      session_id,
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      sample_rate,
206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      frames_per_buffer,
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      sink_params_.effects()));
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebRtcAudioRenderer::~WebRtcAudioRenderer() {
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(state_, UNINITIALIZED);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebRtcAudioRenderer::Initialize(WebRtcAudioRendererSource* source) {
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "WebRtcAudioRenderer::Initialize()";
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock auto_lock(lock_);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(state_, UNINITIALIZED);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(source);
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!sink_.get());
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!source_);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // WebRTC does not yet support higher rates than 96000 on the client side
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // and 48000 is the preferred sample rate. Therefore, if 192000 is detected,
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // we change the rate to 48000 instead. The consequence is that the native
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // layer will be opened up at 192kHz but WebRTC will provide data at 48kHz
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // which will then be resampled by the audio converted on the browser side
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // to match the native audio layer.
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int sample_rate = sink_params_.sample_rate();
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DVLOG(1) << "Audio output hardware sample rate: " << sample_rate;
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (sample_rate == 192000) {
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DVLOG(1) << "Resampling from 48000 to 192000 is required";
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sample_rate = 48000;
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  media::AudioSampleRate asr;
237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (media::ToAudioSampleRate(sample_rate, &asr)) {
238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    UMA_HISTOGRAM_ENUMERATION(
239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        "WebRTC.AudioOutputSampleRate", asr, media::kAudioSampleRateMax + 1);
240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  } else {
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS("WebRTC.AudioOutputSampleRateUnexpected",
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         sample_rate);
243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set up audio parameters for the source, i.e., the WebRTC client.
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The WebRTC client only supports multiples of 10ms as buffer size where
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 10ms is preferred for lowest possible delay.
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  media::AudioParameters source_params;
250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const int frames_per_10ms = (sample_rate / 100);
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DVLOG(1) << "Using WebRTC output buffer size: " << frames_per_10ms;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source_params.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      sink_params_.channel_layout(), sink_params_.channels(),
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      sample_rate, 16, frames_per_10ms);
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const int frames_per_buffer =
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetOptimalBufferSize(sample_rate, sink_params_.frames_per_buffer());
2597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  sink_params_.Reset(sink_params_.format(), sink_params_.channel_layout(),
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     sink_params_.channels(), sample_rate, 16,
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     frames_per_buffer);
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a FIFO if re-buffering is required to match the source input with
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the sink request. The source acts as provider here and the sink as
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // consumer.
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  fifo_delay_milliseconds_ = 0;
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (source_params.frames_per_buffer() != sink_params_.frames_per_buffer()) {
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DVLOG(1) << "Rebuffering from " << source_params.frames_per_buffer()
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             << " to " << sink_params_.frames_per_buffer();
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    audio_fifo_.reset(new media::AudioPullFifo(
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        source_params.channels(),
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        source_params.frames_per_buffer(),
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            &WebRtcAudioRenderer::SourceCallback,
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            base::Unretained(this))));
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (sink_params_.frames_per_buffer() > source_params.frames_per_buffer()) {
279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      int frame_duration_milliseconds = base::Time::kMillisecondsPerSecond /
280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          static_cast<double>(source_params.sample_rate());
281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fifo_delay_milliseconds_ = (sink_params_.frames_per_buffer() -
282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        source_params.frames_per_buffer()) * frame_duration_milliseconds;
283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  source_ = source;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure the audio rendering client and start rendering.
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sink_ = AudioDeviceFactory::NewOutputDevice(
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      source_render_view_id_, source_render_frame_id_);
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK_GE(session_id_, 0);
293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  sink_->InitializeWithSessionId(sink_params_, this, session_id_);
29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sink_->Start();
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // User must call Play() before any audio can be heard.
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state_ = PAUSED;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)scoped_refptr<MediaStreamAudioRenderer>
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)WebRtcAudioRenderer::CreateSharedAudioRendererProxy(
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const scoped_refptr<webrtc::MediaStreamInterface>& media_stream) {
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  content::SharedAudioRenderer::OnPlayStateChanged on_play_state_changed =
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&WebRtcAudioRenderer::OnPlayStateChanged, this);
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return new SharedAudioRenderer(this, media_stream, on_play_state_changed);
30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
31158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool WebRtcAudioRenderer::IsStarted() const {
31258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return start_ref_count_ != 0;
31458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebRtcAudioRenderer::Start() {
31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DVLOG(1) << "WebRtcAudioRenderer::Start()";
31858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ++start_ref_count_;
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebRtcAudioRenderer::Play() {
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "WebRtcAudioRenderer::Play()";
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (playing_state_.playing())
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  playing_state_.set_playing(true);
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  render_callback_count_ = 0;
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  OnPlayStateChanged(media_stream_, &playing_state_);
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebRtcAudioRenderer::EnterPlayState() {
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DVLOG(1) << "WebRtcAudioRenderer::EnterPlayState()";
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK_GT(start_ref_count_, 0) << "Did you forget to call Start()?";
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock auto_lock(lock_);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state_ == UNINITIALIZED)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(play_ref_count_ == 0 || state_ == PLAYING);
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ++play_ref_count_;
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (state_ != PLAYING) {
34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    state_ = PLAYING;
34858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
34958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (audio_fifo_) {
35058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      audio_delay_milliseconds_ = 0;
35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      audio_fifo_->Clear();
35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebRtcAudioRenderer::Pause() {
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "WebRtcAudioRenderer::Pause()";
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!playing_state_.playing())
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  playing_state_.set_playing(false);
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  OnPlayStateChanged(media_stream_, &playing_state_);
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebRtcAudioRenderer::EnterPauseState() {
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DVLOG(1) << "WebRtcAudioRenderer::EnterPauseState()";
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
37058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK_GT(start_ref_count_, 0) << "Did you forget to call Start()?";
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock auto_lock(lock_);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state_ == UNINITIALIZED)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(state_, PLAYING);
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GT(play_ref_count_, 0);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!--play_ref_count_)
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    state_ = PAUSED;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebRtcAudioRenderer::Stop() {
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "WebRtcAudioRenderer::Stop()";
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  {
38558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::AutoLock auto_lock(lock_);
38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (state_ == UNINITIALIZED)
38758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
38858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
38958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (--start_ref_count_)
39058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
39158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
39258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DVLOG(1) << "Calling RemoveAudioRenderer and Stop().";
39358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
39458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    source_->RemoveAudioRenderer(this);
39558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    source_ = NULL;
39658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    state_ = UNINITIALIZED;
39758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Make sure to stop the sink while _not_ holding the lock since the Render()
40058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // callback may currently be executing and try to grab the lock while we're
40158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // stopping the thread on which it runs.
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sink_->Stop();
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebRtcAudioRenderer::SetVolume(float volume) {
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(volume >= 0.0f && volume <= 1.0f);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  playing_state_.set_volume(volume);
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  OnPlayStateChanged(media_stream_, &playing_state_);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::TimeDelta WebRtcAudioRenderer::GetCurrentRenderTime() const {
414f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
415f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::AutoLock auto_lock(lock_);
416f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return current_time_;
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool WebRtcAudioRenderer::IsLocalRenderer() const {
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int WebRtcAudioRenderer::Render(media::AudioBus* audio_bus,
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                int audio_delay_milliseconds) {
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AutoLock auto_lock(lock_);
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!source_)
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(2) << "WebRtcAudioRenderer::Render()";
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(2) << "audio_delay_milliseconds: " << audio_delay_milliseconds;
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  audio_delay_milliseconds_ = audio_delay_milliseconds;
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (audio_fifo_)
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    audio_fifo_->Consume(audio_bus, audio_bus->frames());
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SourceCallback(0, audio_bus);
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (state_ == PLAYING) ? audio_bus->frames() : 0;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebRtcAudioRenderer::OnRenderError() {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTIMPLEMENTED();
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(ERROR) << "OnRenderError()";
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Called by AudioPullFifo when more data is necessary.
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebRtcAudioRenderer::SourceCallback(
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int fifo_frame_delay, media::AudioBus* audio_bus) {
4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeTicks start_time = base::TimeTicks::Now() ;
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(2) << "WebRtcAudioRenderer::SourceCallback("
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           << fifo_frame_delay << ", "
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           << audio_bus->frames() << ")";
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int output_delay_milliseconds = audio_delay_milliseconds_;
456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  output_delay_milliseconds += fifo_delay_milliseconds_;
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(2) << "output_delay_milliseconds: " << output_delay_milliseconds;
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We need to keep render data for the |source_| regardless of |state_|,
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // otherwise the data will be buffered up inside |source_|.
461a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  source_->RenderData(audio_bus, sink_params_.sample_rate(),
462f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                      output_delay_milliseconds,
463f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                      &current_time_);
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Avoid filling up the audio bus if we are not playing; instead
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // return here and ensure that the returned value in Render() is 0.
467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (state_ != PLAYING)
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    audio_bus->Zero();
4691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (++render_callback_count_ == kNumCallbacksBetweenRenderTimeHistograms) {
4711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::TimeDelta elapsed = base::TimeTicks::Now() - start_time;
4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    render_callback_count_ = 0;
4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    UMA_HISTOGRAM_TIMES("WebRTC.AudioRenderTimes", elapsed);
4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebRtcAudioRenderer::UpdateSourceVolume(
4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    webrtc::AudioSourceInterface* source) {
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Note: If there are no playing audio renderers, then the volume will be
4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // set to 0.0.
4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  float volume = 0.0f;
4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SourcePlayingStates::iterator entry = source_playing_states_.find(source);
4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (entry != source_playing_states_.end()) {
4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PlayingStates& states = entry->second;
4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (PlayingStates::const_iterator it = states.begin();
4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         it != states.end(); ++it) {
4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if ((*it)->playing())
4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        volume += (*it)->volume();
4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The valid range for volume scaling of a remote webrtc source is
4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // 0.0-10.0 where 1.0 is no attenuation/boost.
4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(volume >= 0.0f);
4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (volume > 10.0f)
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    volume = 10.0f;
5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DVLOG(1) << "Setting remote source volume: " << volume;
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  source->SetVolume(volume);
5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool WebRtcAudioRenderer::AddPlayingState(
5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    webrtc::AudioSourceInterface* source,
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PlayingState* state) {
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(state->playing());
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Look up or add the |source| to the map.
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PlayingStates& array = source_playing_states_[source];
5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (std::find(array.begin(), array.end(), state) != array.end())
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  array.push_back(state);
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool WebRtcAudioRenderer::RemovePlayingState(
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    webrtc::AudioSourceInterface* source,
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PlayingState* state) {
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!state->playing());
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SourcePlayingStates::iterator found = source_playing_states_.find(source);
5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (found == source_playing_states_.end())
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PlayingStates& array = found->second;
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PlayingStates::iterator state_it =
5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      std::find(array.begin(), array.end(), state);
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (state_it == array.end())
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  array.erase(state_it);
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (array.empty())
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    source_playing_states_.erase(found);
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebRtcAudioRenderer::OnPlayStateChanged(
5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const scoped_refptr<webrtc::MediaStreamInterface>& media_stream,
5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PlayingState* state) {
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  webrtc::AudioTrackVector tracks(media_stream->GetAudioTracks());
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (webrtc::AudioTrackVector::iterator it = tracks.begin();
5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != tracks.end(); ++it) {
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    webrtc::AudioSourceInterface* source = (*it)->GetSource();
5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(source);
5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!state->playing()) {
5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (RemovePlayingState(source, state))
5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EnterPauseState();
5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else if (AddPlayingState(source, state)) {
5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EnterPlayState();
5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UpdateSourceVolume(source);
5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
562