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