Home | History | Annotate | Download | only in services
      1 // Copyright 2014 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 "media/mojo/services/mojo_renderer_service.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/memory/scoped_vector.h"
      9 #include "media/audio/null_audio_sink.h"
     10 #include "media/base/audio_decoder.h"
     11 #include "media/base/audio_renderer.h"
     12 #include "media/base/audio_renderer_sink.h"
     13 #include "media/base/decryptor.h"
     14 #include "media/base/media_log.h"
     15 #include "media/filters/audio_renderer_impl.h"
     16 #include "media/mojo/services/mojo_demuxer_stream_adapter.h"
     17 #include "mojo/application/application_runner_chromium.h"
     18 #include "mojo/public/c/system/main.h"
     19 #include "mojo/public/cpp/application/application_connection.h"
     20 #include "mojo/public/cpp/application/application_delegate.h"
     21 #include "mojo/public/cpp/application/interface_factory_impl.h"
     22 
     23 namespace media {
     24 
     25 class MojoRendererApplication
     26     : public mojo::ApplicationDelegate,
     27       public mojo::InterfaceFactory<mojo::MediaRenderer> {
     28  public:
     29   // mojo::ApplicationDelegate implementation.
     30   virtual bool ConfigureIncomingConnection(
     31       mojo::ApplicationConnection* connection) OVERRIDE {
     32     connection->AddService(this);
     33     return true;
     34   }
     35 
     36   // mojo::InterfaceFactory<mojo::MediaRenderer> implementation.
     37   virtual void Create(
     38       mojo::ApplicationConnection* connection,
     39       mojo::InterfaceRequest<mojo::MediaRenderer> request) OVERRIDE {
     40     mojo::BindToRequest(new MojoRendererService(connection), &request);
     41   }
     42 };
     43 
     44 MojoRendererService::MojoRendererService(
     45     mojo::ApplicationConnection* connection)
     46     : hardware_config_(AudioParameters(), AudioParameters()),
     47       weak_factory_(this),
     48       weak_this_(weak_factory_.GetWeakPtr()) {
     49   scoped_refptr<base::SingleThreadTaskRunner> runner(
     50       base::MessageLoop::current()->task_runner());
     51   scoped_refptr<MediaLog> media_log(new MediaLog());
     52   audio_renderer_.reset(new AudioRendererImpl(
     53       runner,
     54       // TODO(tim): We should use |connection| passed to MojoRendererService
     55       // to connect to a MojoAudioRendererSink implementation that we would
     56       // wrap in an AudioRendererSink and pass in here.
     57       new NullAudioSink(runner),
     58       // TODO(tim): Figure out how to select decoders.
     59       ScopedVector<AudioDecoder>(),
     60       // TODO(tim): Not needed for now?
     61       SetDecryptorReadyCB(),
     62       hardware_config_,
     63       media_log));
     64 }
     65 
     66 MojoRendererService::~MojoRendererService() {
     67 }
     68 
     69 void MojoRendererService::Initialize(mojo::DemuxerStreamPtr stream,
     70                                      const mojo::Callback<void()>& callback) {
     71   DCHECK(client());
     72   stream_.reset(new MojoDemuxerStreamAdapter(
     73       stream.Pass(),
     74       base::Bind(&MojoRendererService::OnStreamReady, weak_this_)));
     75   init_cb_ = callback;
     76 }
     77 
     78 void MojoRendererService::Flush(const mojo::Callback<void()>& callback) {
     79   NOTIMPLEMENTED();
     80 }
     81 
     82 void MojoRendererService::StartPlayingFrom(int64_t time_delta_usec) {
     83   NOTIMPLEMENTED();
     84 }
     85 
     86 void MojoRendererService::SetPlaybackRate(float playback_rate) {
     87   NOTIMPLEMENTED();
     88 }
     89 
     90 void MojoRendererService::SetVolume(float volume) {
     91   NOTIMPLEMENTED();
     92 }
     93 
     94 void MojoRendererService::OnStreamReady() {
     95   audio_renderer_->Initialize(
     96       stream_.get(),
     97       base::Bind(&MojoRendererService::OnAudioRendererInitializeDone,
     98                  weak_this_),
     99       base::Bind(&MojoRendererService::OnUpdateStatistics, weak_this_),
    100       base::Bind(&MojoRendererService::OnBufferingStateChanged, weak_this_),
    101       base::Bind(&MojoRendererService::OnAudioRendererEnded, weak_this_),
    102       base::Bind(&MojoRendererService::OnError, weak_this_));
    103 }
    104 
    105 void MojoRendererService::OnAudioRendererInitializeDone(PipelineStatus status) {
    106   if (status != PIPELINE_OK) {
    107     audio_renderer_.reset();
    108     client()->OnError();
    109   }
    110   init_cb_.Run();
    111 }
    112 
    113 void MojoRendererService::OnUpdateStatistics(const PipelineStatistics& stats) {
    114   NOTIMPLEMENTED();
    115 }
    116 
    117 void MojoRendererService::OnAudioTimeUpdate(base::TimeDelta time,
    118                                             base::TimeDelta max_time) {
    119   client()->OnTimeUpdate(time.InMicroseconds(), max_time.InMicroseconds());
    120 }
    121 
    122 void MojoRendererService::OnBufferingStateChanged(
    123     media::BufferingState new_buffering_state) {
    124   client()->OnBufferingStateChange(
    125       static_cast<mojo::BufferingState>(new_buffering_state));
    126 }
    127 
    128 void MojoRendererService::OnAudioRendererEnded() {
    129   client()->OnEnded();
    130 }
    131 
    132 void MojoRendererService::OnError(PipelineStatus error) {
    133   client()->OnError();
    134 }
    135 
    136 }  // namespace media
    137 
    138 MojoResult MojoMain(MojoHandle shell_handle) {
    139   mojo::ApplicationRunnerChromium runner(new media::MojoRendererApplication);
    140   return runner.Run(shell_handle);
    141 }
    142