| Index: chromecast/media/cma/backend/media_pipeline_backend_default.cc
|
| diff --git a/chromecast/media/cma/backend/media_pipeline_backend_default.cc b/chromecast/media/cma/backend/media_pipeline_backend_default.cc
|
| index f47e2cd7fbe9dff7393a7b900b652a3da73e407c..b41cd4c8b62cf3ee073defcfc597194cad994d36 100644
|
| --- a/chromecast/media/cma/backend/media_pipeline_backend_default.cc
|
| +++ b/chromecast/media/cma/backend/media_pipeline_backend_default.cc
|
| @@ -4,95 +4,115 @@
|
|
|
| #include "chromecast/media/cma/backend/media_pipeline_backend_default.h"
|
|
|
| -#include <algorithm>
|
| -#include <limits>
|
| -
|
| +#include "base/logging.h"
|
| +#include "base/memory/ptr_util.h"
|
| #include "chromecast/media/cma/backend/audio_decoder_default.h"
|
| #include "chromecast/media/cma/backend/video_decoder_default.h"
|
| -#include "chromecast/public/media/cast_decoder_buffer.h"
|
| +#include "media/base/timestamp_constants.h"
|
|
|
| namespace chromecast {
|
| namespace media {
|
|
|
| MediaPipelineBackendDefault::MediaPipelineBackendDefault()
|
| - : start_pts_(std::numeric_limits<int64_t>::min()),
|
| - running_(false),
|
| - rate_(1.0f) {}
|
| + : state_(kStateUninitialized), rate_(1.0f) {}
|
|
|
| MediaPipelineBackendDefault::~MediaPipelineBackendDefault() {
|
| }
|
|
|
| MediaPipelineBackend::AudioDecoder*
|
| MediaPipelineBackendDefault::CreateAudioDecoder() {
|
| + DCHECK_EQ(kStateUninitialized, state_);
|
| DCHECK(!audio_decoder_);
|
| - audio_decoder_.reset(new AudioDecoderDefault());
|
| + audio_decoder_ = base::MakeUnique<AudioDecoderDefault>();
|
| return audio_decoder_.get();
|
| }
|
|
|
| MediaPipelineBackend::VideoDecoder*
|
| MediaPipelineBackendDefault::CreateVideoDecoder() {
|
| + DCHECK_EQ(kStateUninitialized, state_);
|
| DCHECK(!video_decoder_);
|
| - video_decoder_.reset(new VideoDecoderDefault());
|
| + video_decoder_ = base::MakeUnique<VideoDecoderDefault>();
|
| return video_decoder_.get();
|
| }
|
|
|
| bool MediaPipelineBackendDefault::Initialize() {
|
| + DCHECK_EQ(kStateUninitialized, state_);
|
| + state_ = kStateInitialized;
|
| return true;
|
| }
|
|
|
| bool MediaPipelineBackendDefault::Start(int64_t start_pts) {
|
| - DCHECK(!running_);
|
| - start_pts_ = start_pts;
|
| - start_clock_ = base::TimeTicks::Now();
|
| - running_ = true;
|
| + DCHECK_EQ(kStateInitialized, state_);
|
| + if (!audio_decoder_ && !video_decoder_)
|
| + return false;
|
| +
|
| + if (audio_decoder_) {
|
| + audio_decoder_->Start(base::TimeDelta::FromMicroseconds(start_pts));
|
| + audio_decoder_->SetPlaybackRate(rate_);
|
| + }
|
| + if (video_decoder_) {
|
| + video_decoder_->Start(base::TimeDelta::FromMicroseconds(start_pts));
|
| + video_decoder_->SetPlaybackRate(rate_);
|
| + }
|
| + state_ = kStatePlaying;
|
| return true;
|
| }
|
|
|
| void MediaPipelineBackendDefault::Stop() {
|
| - start_pts_ = GetCurrentPts();
|
| - running_ = false;
|
| + DCHECK(state_ == kStatePlaying || state_ == kStatePaused);
|
| + if (audio_decoder_)
|
| + audio_decoder_->Stop();
|
| + if (video_decoder_)
|
| + video_decoder_->Stop();
|
| + state_ = kStateInitialized;
|
| }
|
|
|
| bool MediaPipelineBackendDefault::Pause() {
|
| - DCHECK(running_);
|
| - start_pts_ = GetCurrentPts();
|
| - running_ = false;
|
| + DCHECK_EQ(kStatePlaying, state_);
|
| + if (audio_decoder_)
|
| + audio_decoder_->SetPlaybackRate(0.0f);
|
| + if (video_decoder_)
|
| + video_decoder_->SetPlaybackRate(0.0f);
|
| + state_ = kStatePaused;
|
| return true;
|
| }
|
|
|
| bool MediaPipelineBackendDefault::Resume() {
|
| - DCHECK(!running_);
|
| - running_ = true;
|
| - start_clock_ = base::TimeTicks::Now();
|
| + DCHECK_EQ(kStatePaused, state_);
|
| + if (audio_decoder_)
|
| + audio_decoder_->SetPlaybackRate(rate_);
|
| + if (video_decoder_)
|
| + video_decoder_->SetPlaybackRate(rate_);
|
| + state_ = kStatePlaying;
|
| return true;
|
| }
|
|
|
| int64_t MediaPipelineBackendDefault::GetCurrentPts() {
|
| - if (!running_)
|
| - return start_pts_;
|
| -
|
| - if (audio_decoder_ &&
|
| - audio_decoder_->last_push_pts() != std::numeric_limits<int64_t>::min()) {
|
| - start_pts_ = std::min(start_pts_, audio_decoder_->last_push_pts());
|
| + base::TimeDelta current_pts = ::media::kNoTimestamp;
|
| +
|
| + if (audio_decoder_ && video_decoder_) {
|
| + current_pts = std::min(audio_decoder_->GetCurrentPts(),
|
| + video_decoder_->GetCurrentPts());
|
| + } else if (audio_decoder_) {
|
| + current_pts = audio_decoder_->GetCurrentPts();
|
| + } else if (video_decoder_) {
|
| + current_pts = video_decoder_->GetCurrentPts();
|
| }
|
| - if (video_decoder_ &&
|
| - video_decoder_->last_push_pts() != std::numeric_limits<int64_t>::min()) {
|
| - start_pts_ = std::min(start_pts_, video_decoder_->last_push_pts());
|
| - }
|
| -
|
| - base::TimeTicks now = base::TimeTicks::Now();
|
| - base::TimeDelta interpolated_media_time =
|
| - base::TimeDelta::FromMicroseconds(start_pts_) +
|
| - (now - start_clock_) * rate_;
|
|
|
| - return interpolated_media_time.InMicroseconds();
|
| + return current_pts.InMicroseconds();
|
| }
|
|
|
| bool MediaPipelineBackendDefault::SetPlaybackRate(float rate) {
|
| DCHECK_GT(rate, 0.0f);
|
| - start_pts_ = GetCurrentPts();
|
| - start_clock_ = base::TimeTicks::Now();
|
| rate_ = rate;
|
| +
|
| + if (state_ == kStatePlaying) {
|
| + if (audio_decoder_)
|
| + audio_decoder_->SetPlaybackRate(rate_);
|
| + if (video_decoder_)
|
| + video_decoder_->SetPlaybackRate(rate_);
|
| + }
|
| +
|
| return true;
|
| }
|
|
|
|
|