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