• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tv.tuner.exoplayer.audio;
18 
19 import com.android.tv.common.SoftPreconditions;
20 
21 import android.os.SystemClock;
22 
23 /**
24  * Copy of {@link com.google.android.exoplayer.MediaClock}.
25  * <p>
26  * A simple clock for tracking the progression of media time. The clock can be started, stopped and
27  * its time can be set and retrieved. When started, this clock is based on
28  * {@link SystemClock#elapsedRealtime()}.
29  */
30 /* package */ class AudioClock {
31     private boolean mStarted;
32 
33     /**
34      * The media time when the clock was last set or stopped.
35      */
36     private long mPositionUs;
37 
38     /**
39      * The difference between {@link SystemClock#elapsedRealtime()} and {@link #mPositionUs}
40      * when the clock was last set or mStarted.
41      */
42     private long mDeltaUs;
43 
44     private float mPlaybackSpeed = 1.0f;
45     private long mDeltaUpdatedTimeUs;
46 
47     /**
48      * Starts the clock. Does nothing if the clock is already started.
49      */
start()50     public void start() {
51         if (!mStarted) {
52             mStarted = true;
53             mDeltaUs = elapsedRealtimeMinus(mPositionUs);
54             mDeltaUpdatedTimeUs = SystemClock.elapsedRealtime() * 1000;
55         }
56     }
57 
58     /**
59      * Stops the clock. Does nothing if the clock is already stopped.
60      */
stop()61     public void stop() {
62         if (mStarted) {
63             mPositionUs = elapsedRealtimeMinus(mDeltaUs);
64             mStarted = false;
65         }
66     }
67 
68     /**
69      * @param timeUs The position to set in microseconds.
70      */
setPositionUs(long timeUs)71     public void setPositionUs(long timeUs) {
72         this.mPositionUs = timeUs;
73         mDeltaUs = elapsedRealtimeMinus(timeUs);
74         mDeltaUpdatedTimeUs = SystemClock.elapsedRealtime() * 1000;
75     }
76 
77     /**
78      * @return The current position in microseconds.
79      */
getPositionUs()80     public long getPositionUs() {
81         if (!mStarted) {
82             return mPositionUs;
83         }
84         if (mPlaybackSpeed != 1.0f) {
85             long elapsedTimeFromPlaybackSpeedChanged = SystemClock.elapsedRealtime() * 1000
86                     - mDeltaUpdatedTimeUs;
87             return elapsedRealtimeMinus(mDeltaUs)
88                     + (long) ((mPlaybackSpeed - 1.0f) * elapsedTimeFromPlaybackSpeedChanged);
89         } else {
90             return elapsedRealtimeMinus(mDeltaUs);
91         }
92     }
93 
94     /**
95      * Sets playback speed. {@code speed} should be positive.
96      */
setPlaybackSpeed(float speed)97     public void setPlaybackSpeed(float speed) {
98         SoftPreconditions.checkState(speed > 0);
99         mDeltaUs = elapsedRealtimeMinus(getPositionUs());
100         mDeltaUpdatedTimeUs = SystemClock.elapsedRealtime() * 1000;
101         mPlaybackSpeed = speed;
102     }
103 
elapsedRealtimeMinus(long toSubtractUs)104     private long elapsedRealtimeMinus(long toSubtractUs) {
105         return SystemClock.elapsedRealtime() * 1000 - toSubtractUs;
106     }
107 }
108