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 #include "content/renderer/media/renderer_webaudiodevice_impl.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/logging.h"
      9 #include "content/renderer/media/audio_device_factory.h"
     10 #include "content/renderer/render_frame_impl.h"
     11 #include "content/renderer/render_view_impl.h"
     12 #include "media/audio/audio_output_device.h"
     13 #include "media/base/media_switches.h"
     14 #include "third_party/WebKit/public/web/WebLocalFrame.h"
     15 #include "third_party/WebKit/public/web/WebView.h"
     16 
     17 using blink::WebAudioDevice;
     18 using blink::WebLocalFrame;
     19 using blink::WebVector;
     20 using blink::WebView;
     21 
     22 namespace content {
     23 
     24 RendererWebAudioDeviceImpl::RendererWebAudioDeviceImpl(
     25     const media::AudioParameters& params,
     26     WebAudioDevice::RenderCallback* callback,
     27     int session_id)
     28     : params_(params),
     29       client_callback_(callback),
     30       session_id_(session_id) {
     31   DCHECK(client_callback_);
     32 }
     33 
     34 RendererWebAudioDeviceImpl::~RendererWebAudioDeviceImpl() {
     35   DCHECK(!output_device_.get());
     36 }
     37 
     38 void RendererWebAudioDeviceImpl::start() {
     39   DCHECK(thread_checker_.CalledOnValidThread());
     40 
     41   if (output_device_.get())
     42     return;  // Already started.
     43 
     44   // Assumption: This method is being invoked within a V8 call stack.  CHECKs
     45   // will fail in the call to frameForCurrentContext() otherwise.
     46   //
     47   // Therefore, we can perform look-ups to determine which RenderView is
     48   // starting the audio device.  The reason for all this is because the creator
     49   // of the WebAudio objects might not be the actual source of the audio (e.g.,
     50   // an extension creates a object that is passed and used within a page).
     51   WebLocalFrame* const web_frame = WebLocalFrame::frameForCurrentContext();
     52   WebView* const web_view = web_frame ? web_frame->view() : NULL;
     53   RenderFrame* const render_frame =
     54       web_frame ? RenderFrame::FromWebFrame(web_frame) : NULL;
     55   RenderViewImpl* const render_view =
     56       web_view ? RenderViewImpl::FromWebView(web_view) : NULL;
     57   output_device_ = AudioDeviceFactory::NewOutputDevice(
     58       render_view ? render_view->routing_id() : MSG_ROUTING_NONE,
     59       render_frame ? render_frame->GetRoutingID(): MSG_ROUTING_NONE);
     60   output_device_->InitializeWithSessionId(params_, this, session_id_);
     61   output_device_->Start();
     62   // Note: Default behavior is to auto-play on start.
     63 }
     64 
     65 void RendererWebAudioDeviceImpl::stop() {
     66   DCHECK(thread_checker_.CalledOnValidThread());
     67 
     68   if (output_device_.get()) {
     69     output_device_->Stop();
     70     output_device_ = NULL;
     71   }
     72 }
     73 
     74 double RendererWebAudioDeviceImpl::sampleRate() {
     75   return params_.sample_rate();
     76 }
     77 
     78 int RendererWebAudioDeviceImpl::Render(media::AudioBus* dest,
     79                                        int audio_delay_milliseconds) {
     80   if (client_callback_) {
     81     // Wrap the output pointers using WebVector.
     82     WebVector<float*> web_audio_dest_data(
     83         static_cast<size_t>(dest->channels()));
     84     for (int i = 0; i < dest->channels(); ++i)
     85       web_audio_dest_data[i] = dest->channel(i);
     86 
     87     // TODO(xians): Remove the following |web_audio_source_data| after
     88     // changing the blink interface.
     89     WebVector<float*> web_audio_source_data(static_cast<size_t>(0));
     90     client_callback_->render(web_audio_source_data,
     91                              web_audio_dest_data,
     92                              dest->frames());
     93   }
     94 
     95   return dest->frames();
     96 }
     97 
     98 void RendererWebAudioDeviceImpl::OnRenderError() {
     99   // TODO(crogers): implement error handling.
    100 }
    101 
    102 }  // namespace content
    103