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_clock_device_default.h" | 5 #include "chromecast/media/cma/backend/media_clock_device_default.h" |
6 | 6 |
7 #include "media/base/buffers.h" | 7 #include "media/base/buffers.h" |
8 | 8 |
9 namespace chromecast { | 9 namespace chromecast { |
10 namespace media { | 10 namespace media { |
| 11 namespace { |
| 12 |
| 13 // Return true if transition from |state1| to |state2| is a valid state |
| 14 // transition. |
| 15 inline static bool IsValidStateTransition(MediaClockDevice::State state1, |
| 16 MediaClockDevice::State state2) { |
| 17 if (state2 == state1) |
| 18 return true; |
| 19 |
| 20 // All states can transition to |kStateError|. |
| 21 if (state2 == MediaClockDevice::kStateError) |
| 22 return true; |
| 23 |
| 24 // All the other valid FSM transitions. |
| 25 switch (state1) { |
| 26 case MediaClockDevice::kStateUninitialized: |
| 27 return state2 == MediaClockDevice::kStateIdle; |
| 28 case MediaClockDevice::kStateIdle: |
| 29 return state2 == MediaClockDevice::kStateRunning || |
| 30 state2 == MediaClockDevice::kStateUninitialized; |
| 31 case MediaClockDevice::kStateRunning: |
| 32 return state2 == MediaClockDevice::kStateIdle; |
| 33 case MediaClockDevice::kStateError: |
| 34 return state2 == MediaClockDevice::kStateUninitialized; |
| 35 default: |
| 36 return false; |
| 37 } |
| 38 } |
| 39 |
| 40 } // namespace |
11 | 41 |
12 MediaClockDeviceDefault::MediaClockDeviceDefault() | 42 MediaClockDeviceDefault::MediaClockDeviceDefault() |
13 : state_(kStateUninitialized), | 43 : state_(kStateUninitialized), media_time_(::media::kNoTimestamp()) { |
14 media_time_(::media::kNoTimestamp()) { | 44 thread_checker_.DetachFromThread(); |
15 DetachFromThread(); | |
16 } | 45 } |
17 | 46 |
18 MediaClockDeviceDefault::~MediaClockDeviceDefault() { | 47 MediaClockDeviceDefault::~MediaClockDeviceDefault() { |
19 } | 48 } |
20 | 49 |
21 MediaClockDevice::State MediaClockDeviceDefault::GetState() const { | 50 MediaClockDevice::State MediaClockDeviceDefault::GetState() const { |
22 DCHECK(CalledOnValidThread()); | 51 DCHECK(thread_checker_.CalledOnValidThread()); |
23 return state_; | 52 return state_; |
24 } | 53 } |
25 | 54 |
26 bool MediaClockDeviceDefault::SetState(State new_state) { | 55 bool MediaClockDeviceDefault::SetState(State new_state) { |
27 DCHECK(CalledOnValidThread()); | 56 DCHECK(thread_checker_.CalledOnValidThread()); |
28 if (!MediaClockDevice::IsValidStateTransition(state_, new_state)) | 57 DCHECK(IsValidStateTransition(state_, new_state)); |
29 return false; | |
30 | 58 |
31 if (new_state == state_) | 59 if (new_state == state_) |
32 return true; | 60 return true; |
33 | 61 |
34 state_ = new_state; | 62 state_ = new_state; |
35 | 63 |
36 if (state_ == kStateRunning) { | 64 if (state_ == kStateRunning) { |
37 stc_ = base::TimeTicks::Now(); | 65 stc_ = base::TimeTicks::Now(); |
38 DCHECK(media_time_ != ::media::kNoTimestamp()); | 66 DCHECK(media_time_ != ::media::kNoTimestamp()); |
39 return true; | 67 return true; |
40 } | 68 } |
41 | 69 |
42 if (state_ == kStateIdle) { | 70 if (state_ == kStateIdle) { |
43 media_time_ = ::media::kNoTimestamp(); | 71 media_time_ = ::media::kNoTimestamp(); |
44 return true; | 72 return true; |
45 } | 73 } |
46 | 74 |
47 return true; | 75 return true; |
48 } | 76 } |
49 | 77 |
50 bool MediaClockDeviceDefault::ResetTimeline(base::TimeDelta time) { | 78 bool MediaClockDeviceDefault::ResetTimeline(int64_t time_microseconds) { |
51 DCHECK(CalledOnValidThread()); | 79 DCHECK(thread_checker_.CalledOnValidThread()); |
52 DCHECK_EQ(state_, kStateIdle); | 80 DCHECK_EQ(state_, kStateIdle); |
53 media_time_ = time; | 81 media_time_ = base::TimeDelta::FromMicroseconds(time_microseconds); |
54 return true; | 82 return true; |
55 } | 83 } |
56 | 84 |
57 bool MediaClockDeviceDefault::SetRate(float rate) { | 85 bool MediaClockDeviceDefault::SetRate(float rate) { |
58 DCHECK(CalledOnValidThread()); | 86 DCHECK(thread_checker_.CalledOnValidThread()); |
59 if (state_ == kStateRunning) { | 87 if (state_ == kStateRunning) { |
60 base::TimeTicks now = base::TimeTicks::Now(); | 88 base::TimeTicks now = base::TimeTicks::Now(); |
61 media_time_ = media_time_ + (now - stc_) * rate_; | 89 media_time_ = media_time_ + (now - stc_) * rate_; |
62 stc_ = now; | 90 stc_ = now; |
63 } | 91 } |
64 | 92 |
65 rate_ = rate; | 93 rate_ = rate; |
66 return true; | 94 return true; |
67 } | 95 } |
68 | 96 |
69 base::TimeDelta MediaClockDeviceDefault::GetTime() { | 97 int64_t MediaClockDeviceDefault::GetTimeMicroseconds() { |
70 DCHECK(CalledOnValidThread()); | 98 DCHECK(thread_checker_.CalledOnValidThread()); |
71 if (state_ != kStateRunning) | 99 if (state_ != kStateRunning) |
72 return media_time_; | 100 return media_time_.InMicroseconds(); |
73 | 101 |
74 if (media_time_ == ::media::kNoTimestamp()) | 102 if (media_time_ == ::media::kNoTimestamp()) |
75 return ::media::kNoTimestamp(); | 103 return media_time_.InMicroseconds(); |
76 | 104 |
77 base::TimeTicks now = base::TimeTicks::Now(); | 105 base::TimeTicks now = base::TimeTicks::Now(); |
78 base::TimeDelta interpolated_media_time = | 106 base::TimeDelta interpolated_media_time = |
79 media_time_ + (now - stc_) * rate_; | 107 media_time_ + (now - stc_) * rate_; |
80 return interpolated_media_time; | 108 return interpolated_media_time.InMicroseconds(); |
81 } | 109 } |
82 | 110 |
83 } // namespace media | 111 } // namespace media |
84 } // namespace chromecast | 112 } // namespace chromecast |
OLD | NEW |