chromium/chromecast/media/cma/backend/android/media_pipeline_backend_android.cc

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

#include "chromecast/media/cma/backend/android/media_pipeline_backend_android.h"

#include <limits>

#include "base/logging.h"
#include "base/task/single_thread_task_runner.h"
#include "chromecast/base/task_runner_impl.h"
#include "chromecast/media/cma/backend/android/audio_decoder_android.h"
#include "chromecast/media/cma/backend/video_decoder_null.h"

namespace chromecast {
namespace media {

MediaPipelineBackendAndroid::MediaPipelineBackendAndroid(
    const MediaPipelineDeviceParams& params)
    : state_(kStateUninitialized), params_(params) {
  LOG(INFO) << __func__ << ":";
}

MediaPipelineBackendAndroid::~MediaPipelineBackendAndroid() {}

MediaPipelineBackendAndroid::AudioDecoder*
MediaPipelineBackendAndroid::CreateAudioDecoder() {
  LOG(INFO) << __func__ << ":";
  DCHECK_EQ(kStateUninitialized, state_);
  if (audio_decoder_)
    return nullptr;
  audio_decoder_.reset(new AudioDecoderAndroid(
      this, params_.sync_type == MediaPipelineDeviceParams::kModeApkSyncPts));
  return audio_decoder_.get();
}

MediaPipelineBackendAndroid::VideoDecoder*
MediaPipelineBackendAndroid::CreateVideoDecoder() {
  LOG(INFO) << __func__ << ":";
  DCHECK_EQ(kStateUninitialized, state_);
  if (video_decoder_)
    return nullptr;
  video_decoder_.reset(new VideoDecoderNull());
  return video_decoder_.get();
}

bool MediaPipelineBackendAndroid::Initialize() {
  LOG(INFO) << __func__ << ":";
  DCHECK_EQ(kStateUninitialized, state_);
  if (audio_decoder_)
    audio_decoder_->Initialize();
  state_ = kStateInitialized;
  return true;
}

bool MediaPipelineBackendAndroid::Start(int64_t start_pts) {
  LOG(INFO) << __func__ << ": start_pts=" << start_pts;
  DCHECK_EQ(kStateInitialized, state_);
  if (audio_decoder_ && !audio_decoder_->Start(start_pts))
    return false;
  state_ = kStatePlaying;
  return true;
}

void MediaPipelineBackendAndroid::Stop() {
  LOG(INFO) << __func__ << ":";
  DCHECK(state_ == kStatePlaying || state_ == kStatePaused)
      << "Invalid state " << state_;
  if (audio_decoder_)
    audio_decoder_->Stop();

  state_ = kStateInitialized;
}

bool MediaPipelineBackendAndroid::Pause() {
  LOG(INFO) << __func__ << ":";
  DCHECK_EQ(kStatePlaying, state_);
  if (audio_decoder_ && !audio_decoder_->Pause())
    return false;
  state_ = kStatePaused;
  return true;
}

bool MediaPipelineBackendAndroid::Resume() {
  LOG(INFO) << __func__ << ":";
  DCHECK_EQ(kStatePaused, state_);
  if (audio_decoder_ && !audio_decoder_->Resume())
    return false;
  state_ = kStatePlaying;
  return true;
}

bool MediaPipelineBackendAndroid::SetPlaybackRate(float rate) {
  LOG(INFO) << __func__ << ": rate=" << rate;
  if (audio_decoder_) {
    return audio_decoder_->SetPlaybackRate(rate);
  }
  return true;
}

int64_t MediaPipelineBackendAndroid::GetCurrentPts() {
  if (audio_decoder_) {
    int64_t pts = audio_decoder_->current_pts();
    DVLOG(2) << __func__ << ": pts=" << pts;
    return pts;
  }
  LOG(INFO) << __func__ << ": pts=<invalid>";
  return std::numeric_limits<int64_t>::min();
}

bool MediaPipelineBackendAndroid::Primary() const {
  return (params_.audio_type !=
          MediaPipelineDeviceParams::kAudioStreamSoundEffects);
}

std::string MediaPipelineBackendAndroid::DeviceId() const {
  return params_.device_id;
}

AudioContentType MediaPipelineBackendAndroid::ContentType() const {
  return params_.content_type;
}

AudioChannel MediaPipelineBackendAndroid::AudioChannel() const {
  return params_.audio_channel;
}

const scoped_refptr<base::SingleThreadTaskRunner>&
MediaPipelineBackendAndroid::GetTaskRunner() const {
  return static_cast<TaskRunnerImpl*>(params_.task_runner)->runner();
}

}  // namespace media
}  // namespace chromecast