OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chromecast/media/cma/backend/media_clock_device_default.h" | |
6 | |
7 #include "media/base/timestamp_constants.h" | |
8 | |
9 namespace chromecast { | |
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 | |
41 | |
42 MediaClockDeviceDefault::MediaClockDeviceDefault() | |
43 : state_(kStateUninitialized), | |
44 media_time_(::media::kNoTimestamp()), | |
45 rate_(0.0f) { | |
46 thread_checker_.DetachFromThread(); | |
47 } | |
48 | |
49 MediaClockDeviceDefault::~MediaClockDeviceDefault() { | |
50 } | |
51 | |
52 MediaClockDevice::State MediaClockDeviceDefault::GetState() const { | |
53 DCHECK(thread_checker_.CalledOnValidThread()); | |
54 return state_; | |
55 } | |
56 | |
57 bool MediaClockDeviceDefault::SetState(State new_state) { | |
58 DCHECK(thread_checker_.CalledOnValidThread()); | |
59 DCHECK(IsValidStateTransition(state_, new_state)); | |
60 | |
61 if (new_state == state_) | |
62 return true; | |
63 | |
64 state_ = new_state; | |
65 | |
66 if (state_ == kStateRunning) { | |
67 stc_ = base::TimeTicks::Now(); | |
68 DCHECK(media_time_ != ::media::kNoTimestamp()); | |
69 return true; | |
70 } | |
71 | |
72 if (state_ == kStateIdle) { | |
73 media_time_ = ::media::kNoTimestamp(); | |
74 return true; | |
75 } | |
76 | |
77 return true; | |
78 } | |
79 | |
80 bool MediaClockDeviceDefault::ResetTimeline(int64_t time_microseconds) { | |
81 DCHECK(thread_checker_.CalledOnValidThread()); | |
82 DCHECK_EQ(state_, kStateIdle); | |
83 media_time_ = base::TimeDelta::FromMicroseconds(time_microseconds); | |
84 return true; | |
85 } | |
86 | |
87 bool MediaClockDeviceDefault::SetRate(float rate) { | |
88 DCHECK(thread_checker_.CalledOnValidThread()); | |
89 if (state_ == kStateRunning) { | |
90 base::TimeTicks now = base::TimeTicks::Now(); | |
91 media_time_ = media_time_ + (now - stc_) * rate_; | |
92 stc_ = now; | |
93 } | |
94 | |
95 rate_ = rate; | |
96 return true; | |
97 } | |
98 | |
99 int64_t MediaClockDeviceDefault::GetTimeMicroseconds() { | |
100 DCHECK(thread_checker_.CalledOnValidThread()); | |
101 if (state_ != kStateRunning) | |
102 return media_time_.InMicroseconds(); | |
103 | |
104 if (media_time_ == ::media::kNoTimestamp()) | |
105 return media_time_.InMicroseconds(); | |
106 | |
107 base::TimeTicks now = base::TimeTicks::Now(); | |
108 base::TimeDelta interpolated_media_time = | |
109 media_time_ + (now - stc_) * rate_; | |
110 return interpolated_media_time.InMicroseconds(); | |
111 } | |
112 | |
113 } // namespace media | |
114 } // namespace chromecast | |
OLD | NEW |