11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/mojo/services/mojo_renderer_service.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/memory/scoped_vector.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/audio/null_audio_sink.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/audio_decoder.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/audio_renderer.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/audio_renderer_sink.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/decryptor.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/media_log.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/filters/audio_renderer_impl.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/mojo/services/mojo_demuxer_stream_adapter.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/application/application_runner_chromium.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/public/c/system/main.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/public/cpp/application/application_connection.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/public/cpp/application/application_delegate.h"
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/public/cpp/application/interface_factory_impl.h"
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace media {
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass MojoRendererApplication
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : public mojo::ApplicationDelegate,
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      public mojo::InterfaceFactory<mojo::MediaRenderer> {
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // mojo::ApplicationDelegate implementation.
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual bool ConfigureIncomingConnection(
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      mojo::ApplicationConnection* connection) OVERRIDE {
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    connection->AddService(this);
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return true;
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // mojo::InterfaceFactory<mojo::MediaRenderer> implementation.
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void Create(
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      mojo::ApplicationConnection* connection,
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      mojo::InterfaceRequest<mojo::MediaRenderer> request) OVERRIDE {
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    mojo::BindToRequest(new MojoRendererService(connection), &request);
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciMojoRendererService::MojoRendererService(
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    mojo::ApplicationConnection* connection)
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : hardware_config_(AudioParameters(), AudioParameters()),
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      weak_factory_(this),
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      weak_this_(weak_factory_.GetWeakPtr()) {
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<base::SingleThreadTaskRunner> runner(
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::MessageLoop::current()->task_runner());
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<MediaLog> media_log(new MediaLog());
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  audio_renderer_.reset(new AudioRendererImpl(
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      runner,
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // TODO(tim): We should use |connection| passed to MojoRendererService
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // to connect to a MojoAudioRendererSink implementation that we would
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // wrap in an AudioRendererSink and pass in here.
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new NullAudioSink(runner),
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // TODO(tim): Figure out how to select decoders.
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ScopedVector<AudioDecoder>(),
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // TODO(tim): Not needed for now?
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SetDecryptorReadyCB(),
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      hardware_config_,
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      media_log));
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciMojoRendererService::~MojoRendererService() {
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MojoRendererService::Initialize(mojo::DemuxerStreamPtr stream,
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     const mojo::Callback<void()>& callback) {
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(client());
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  stream_.reset(new MojoDemuxerStreamAdapter(
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      stream.Pass(),
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&MojoRendererService::OnStreamReady, weak_this_)));
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  init_cb_ = callback;
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MojoRendererService::Flush(const mojo::Callback<void()>& callback) {
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NOTIMPLEMENTED();
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MojoRendererService::StartPlayingFrom(int64_t time_delta_usec) {
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NOTIMPLEMENTED();
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MojoRendererService::SetPlaybackRate(float playback_rate) {
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NOTIMPLEMENTED();
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MojoRendererService::SetVolume(float volume) {
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NOTIMPLEMENTED();
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MojoRendererService::OnStreamReady() {
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  audio_renderer_->Initialize(
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      stream_.get(),
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&MojoRendererService::OnAudioRendererInitializeDone,
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 weak_this_),
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&MojoRendererService::OnUpdateStatistics, weak_this_),
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&MojoRendererService::OnBufferingStateChanged, weak_this_),
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&MojoRendererService::OnAudioRendererEnded, weak_this_),
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&MojoRendererService::OnError, weak_this_));
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MojoRendererService::OnAudioRendererInitializeDone(PipelineStatus status) {
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (status != PIPELINE_OK) {
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    audio_renderer_.reset();
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    client()->OnError();
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  init_cb_.Run();
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MojoRendererService::OnUpdateStatistics(const PipelineStatistics& stats) {
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NOTIMPLEMENTED();
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MojoRendererService::OnAudioTimeUpdate(base::TimeDelta time,
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                            base::TimeDelta max_time) {
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client()->OnTimeUpdate(time.InMicroseconds(), max_time.InMicroseconds());
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MojoRendererService::OnBufferingStateChanged(
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    media::BufferingState new_buffering_state) {
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client()->OnBufferingStateChange(
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      static_cast<mojo::BufferingState>(new_buffering_state));
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MojoRendererService::OnAudioRendererEnded() {
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client()->OnEnded();
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MojoRendererService::OnError(PipelineStatus error) {
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client()->OnError();
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace media
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciMojoResult MojoMain(MojoHandle shell_handle) {
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  mojo::ApplicationRunnerChromium runner(new media::MojoRendererApplication);
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return runner.Run(shell_handle);
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
142