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; |
} |