| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromecast/media/cma/backend/media_pipeline_backend_default.h" | 5 #include "chromecast/media/cma/backend/media_pipeline_backend_default.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include "base/logging.h" |
| 8 #include <limits> | 8 #include "base/memory/ptr_util.h" |
| 9 | |
| 10 #include "chromecast/media/cma/backend/audio_decoder_default.h" | 9 #include "chromecast/media/cma/backend/audio_decoder_default.h" |
| 11 #include "chromecast/media/cma/backend/video_decoder_default.h" | 10 #include "chromecast/media/cma/backend/video_decoder_default.h" |
| 12 #include "chromecast/public/media/cast_decoder_buffer.h" | 11 #include "media/base/timestamp_constants.h" |
| 13 | 12 |
| 14 namespace chromecast { | 13 namespace chromecast { |
| 15 namespace media { | 14 namespace media { |
| 16 | 15 |
| 17 MediaPipelineBackendDefault::MediaPipelineBackendDefault() | 16 MediaPipelineBackendDefault::MediaPipelineBackendDefault() |
| 18 : start_pts_(std::numeric_limits<int64_t>::min()), | 17 : state_(kStateUninitialized), rate_(1.0f) {} |
| 19 running_(false), | |
| 20 rate_(1.0f) {} | |
| 21 | 18 |
| 22 MediaPipelineBackendDefault::~MediaPipelineBackendDefault() { | 19 MediaPipelineBackendDefault::~MediaPipelineBackendDefault() { |
| 23 } | 20 } |
| 24 | 21 |
| 25 MediaPipelineBackend::AudioDecoder* | 22 MediaPipelineBackend::AudioDecoder* |
| 26 MediaPipelineBackendDefault::CreateAudioDecoder() { | 23 MediaPipelineBackendDefault::CreateAudioDecoder() { |
| 24 DCHECK_EQ(kStateUninitialized, state_); |
| 27 DCHECK(!audio_decoder_); | 25 DCHECK(!audio_decoder_); |
| 28 audio_decoder_.reset(new AudioDecoderDefault()); | 26 audio_decoder_ = base::MakeUnique<AudioDecoderDefault>(); |
| 29 return audio_decoder_.get(); | 27 return audio_decoder_.get(); |
| 30 } | 28 } |
| 31 | 29 |
| 32 MediaPipelineBackend::VideoDecoder* | 30 MediaPipelineBackend::VideoDecoder* |
| 33 MediaPipelineBackendDefault::CreateVideoDecoder() { | 31 MediaPipelineBackendDefault::CreateVideoDecoder() { |
| 32 DCHECK_EQ(kStateUninitialized, state_); |
| 34 DCHECK(!video_decoder_); | 33 DCHECK(!video_decoder_); |
| 35 video_decoder_.reset(new VideoDecoderDefault()); | 34 video_decoder_ = base::MakeUnique<VideoDecoderDefault>(); |
| 36 return video_decoder_.get(); | 35 return video_decoder_.get(); |
| 37 } | 36 } |
| 38 | 37 |
| 39 bool MediaPipelineBackendDefault::Initialize() { | 38 bool MediaPipelineBackendDefault::Initialize() { |
| 39 DCHECK_EQ(kStateUninitialized, state_); |
| 40 state_ = kStateInitialized; |
| 40 return true; | 41 return true; |
| 41 } | 42 } |
| 42 | 43 |
| 43 bool MediaPipelineBackendDefault::Start(int64_t start_pts) { | 44 bool MediaPipelineBackendDefault::Start(int64_t start_pts) { |
| 44 DCHECK(!running_); | 45 DCHECK_EQ(kStateInitialized, state_); |
| 45 start_pts_ = start_pts; | 46 if (!audio_decoder_ && !video_decoder_) |
| 46 start_clock_ = base::TimeTicks::Now(); | 47 return false; |
| 47 running_ = true; | 48 |
| 49 if (audio_decoder_) { |
| 50 audio_decoder_->Start(base::TimeDelta::FromMicroseconds(start_pts)); |
| 51 audio_decoder_->SetPlaybackRate(rate_); |
| 52 } |
| 53 if (video_decoder_) { |
| 54 video_decoder_->Start(base::TimeDelta::FromMicroseconds(start_pts)); |
| 55 video_decoder_->SetPlaybackRate(rate_); |
| 56 } |
| 57 state_ = kStatePlaying; |
| 48 return true; | 58 return true; |
| 49 } | 59 } |
| 50 | 60 |
| 51 void MediaPipelineBackendDefault::Stop() { | 61 void MediaPipelineBackendDefault::Stop() { |
| 52 start_pts_ = GetCurrentPts(); | 62 DCHECK(state_ == kStatePlaying || state_ == kStatePaused); |
| 53 running_ = false; | 63 if (audio_decoder_) |
| 64 audio_decoder_->Stop(); |
| 65 if (video_decoder_) |
| 66 video_decoder_->Stop(); |
| 67 state_ = kStateInitialized; |
| 54 } | 68 } |
| 55 | 69 |
| 56 bool MediaPipelineBackendDefault::Pause() { | 70 bool MediaPipelineBackendDefault::Pause() { |
| 57 DCHECK(running_); | 71 DCHECK_EQ(kStatePlaying, state_); |
| 58 start_pts_ = GetCurrentPts(); | 72 if (audio_decoder_) |
| 59 running_ = false; | 73 audio_decoder_->SetPlaybackRate(0.0f); |
| 74 if (video_decoder_) |
| 75 video_decoder_->SetPlaybackRate(0.0f); |
| 76 state_ = kStatePaused; |
| 60 return true; | 77 return true; |
| 61 } | 78 } |
| 62 | 79 |
| 63 bool MediaPipelineBackendDefault::Resume() { | 80 bool MediaPipelineBackendDefault::Resume() { |
| 64 DCHECK(!running_); | 81 DCHECK_EQ(kStatePaused, state_); |
| 65 running_ = true; | 82 if (audio_decoder_) |
| 66 start_clock_ = base::TimeTicks::Now(); | 83 audio_decoder_->SetPlaybackRate(rate_); |
| 84 if (video_decoder_) |
| 85 video_decoder_->SetPlaybackRate(rate_); |
| 86 state_ = kStatePlaying; |
| 67 return true; | 87 return true; |
| 68 } | 88 } |
| 69 | 89 |
| 70 int64_t MediaPipelineBackendDefault::GetCurrentPts() { | 90 int64_t MediaPipelineBackendDefault::GetCurrentPts() { |
| 71 if (!running_) | 91 base::TimeDelta current_pts = ::media::kNoTimestamp; |
| 72 return start_pts_; | |
| 73 | 92 |
| 74 if (audio_decoder_ && | 93 if (audio_decoder_ && video_decoder_) { |
| 75 audio_decoder_->last_push_pts() != std::numeric_limits<int64_t>::min()) { | 94 current_pts = std::min(audio_decoder_->GetCurrentPts(), |
| 76 start_pts_ = std::min(start_pts_, audio_decoder_->last_push_pts()); | 95 video_decoder_->GetCurrentPts()); |
| 77 } | 96 } else if (audio_decoder_) { |
| 78 if (video_decoder_ && | 97 current_pts = audio_decoder_->GetCurrentPts(); |
| 79 video_decoder_->last_push_pts() != std::numeric_limits<int64_t>::min()) { | 98 } else if (video_decoder_) { |
| 80 start_pts_ = std::min(start_pts_, video_decoder_->last_push_pts()); | 99 current_pts = video_decoder_->GetCurrentPts(); |
| 81 } | 100 } |
| 82 | 101 |
| 83 base::TimeTicks now = base::TimeTicks::Now(); | 102 return current_pts.InMicroseconds(); |
| 84 base::TimeDelta interpolated_media_time = | |
| 85 base::TimeDelta::FromMicroseconds(start_pts_) + | |
| 86 (now - start_clock_) * rate_; | |
| 87 | |
| 88 return interpolated_media_time.InMicroseconds(); | |
| 89 } | 103 } |
| 90 | 104 |
| 91 bool MediaPipelineBackendDefault::SetPlaybackRate(float rate) { | 105 bool MediaPipelineBackendDefault::SetPlaybackRate(float rate) { |
| 92 DCHECK_GT(rate, 0.0f); | 106 DCHECK_GT(rate, 0.0f); |
| 93 start_pts_ = GetCurrentPts(); | |
| 94 start_clock_ = base::TimeTicks::Now(); | |
| 95 rate_ = rate; | 107 rate_ = rate; |
| 108 |
| 109 if (state_ == kStatePlaying) { |
| 110 if (audio_decoder_) |
| 111 audio_decoder_->SetPlaybackRate(rate_); |
| 112 if (video_decoder_) |
| 113 video_decoder_->SetPlaybackRate(rate_); |
| 114 } |
| 115 |
| 96 return true; | 116 return true; |
| 97 } | 117 } |
| 98 | 118 |
| 99 } // namespace media | 119 } // namespace media |
| 100 } // namespace chromecast | 120 } // namespace chromecast |
| OLD | NEW |