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 |