普通文本  |  128行  |  4.17 KB

// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/mojo/services/mojo_renderer_impl.h"

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/single_thread_task_runner.h"
#include "media/base/demuxer_stream_provider.h"
#include "media/mojo/services/mojo_demuxer_stream_impl.h"
#include "mojo/public/cpp/application/connect.h"
#include "mojo/public/cpp/bindings/interface_impl.h"
#include "mojo/public/interfaces/application/service_provider.mojom.h"

namespace media {

MojoRendererImpl::MojoRendererImpl(
    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
    DemuxerStreamProvider* demuxer_stream_provider,
    mojo::ServiceProvider* audio_renderer_provider)
    : task_runner_(task_runner),
      demuxer_stream_provider_(demuxer_stream_provider),
      weak_factory_(this) {
  // For now we only support audio and there must be a provider.
  DCHECK(audio_renderer_provider);
  mojo::ConnectToService(audio_renderer_provider, &remote_audio_renderer_);
  remote_audio_renderer_.set_client(this);
}

MojoRendererImpl::~MojoRendererImpl() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  // Connection to |remote_audio_renderer_| will error-out here.
}

void MojoRendererImpl::Initialize(const base::Closure& init_cb,
                                  const StatisticsCB& statistics_cb,
                                  const base::Closure& ended_cb,
                                  const PipelineStatusCB& error_cb,
                                  const BufferingStateCB& buffering_state_cb) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  init_cb_ = init_cb;
  ended_cb_ = ended_cb;
  error_cb_ = error_cb;
  buffering_state_cb_ = buffering_state_cb;

  // Create a mojo::DemuxerStream and bind its lifetime to the pipe.
  mojo::DemuxerStreamPtr demuxer_stream;
  mojo::BindToProxy(
      new MojoDemuxerStreamImpl(
          demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO)),
      &demuxer_stream);
  remote_audio_renderer_->Initialize(demuxer_stream.Pass(), init_cb);
}

void MojoRendererImpl::Flush(const base::Closure& flush_cb) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  remote_audio_renderer_->Flush(flush_cb);
}

void MojoRendererImpl::StartPlayingFrom(base::TimeDelta time) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  remote_audio_renderer_->StartPlayingFrom(time.InMicroseconds());
}

void MojoRendererImpl::SetPlaybackRate(float playback_rate) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  remote_audio_renderer_->SetPlaybackRate(playback_rate);
}

void MojoRendererImpl::SetVolume(float volume) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  remote_audio_renderer_->SetVolume(volume);
}

base::TimeDelta MojoRendererImpl::GetMediaTime() {
  NOTIMPLEMENTED();
  return base::TimeDelta();
}

bool MojoRendererImpl::HasAudio() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK(remote_audio_renderer_.get());  // We always bind the renderer.
  return true;
}

bool MojoRendererImpl::HasVideo() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  return false;
}

void MojoRendererImpl::SetCdm(MediaKeys* cdm) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  NOTIMPLEMENTED();
}

void MojoRendererImpl::OnTimeUpdate(int64_t time_usec, int64_t max_time_usec) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  NOTIMPLEMENTED();
}

void MojoRendererImpl::OnBufferingStateChange(mojo::BufferingState state) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  buffering_state_cb_.Run(static_cast<media::BufferingState>(state));
}

void MojoRendererImpl::OnEnded() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  ended_cb_.Run();
}

void MojoRendererImpl::OnError() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  // TODO(tim): Should we plumb error code from remote renderer?
  // http://crbug.com/410451.
  if (init_cb_.is_null())  // We have initialized already.
    error_cb_.Run(PIPELINE_ERROR_DECODE);
  else
    error_cb_.Run(PIPELINE_ERROR_COULD_NOT_RENDER);
}

void MojoRendererImpl::OnInitialized() {
  DCHECK(!init_cb_.is_null());
  base::ResetAndReturn(&init_cb_).Run();
}

}  // namespace media